2012-05-12 2 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

당신은 다음과 같은 프로세스 내에서 프로그래밍 주석 프로세서와 자바 컴파일러를 호출 할 수

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)); 
    } 
} 

당신이 다음 자동에 META-INF/services/javax.annotation.processing.Processor 파일을 기반으로 주석 프로세서를 감지 setProcessors에 전화를 제거하는 경우 classpath.

3

이것은 my answer to a similar question에 대한 링크입니다.

질문에서 제안하는 방식대로 주석 처리를 할 수는 있지만 어쨌든 annotationsroundEnv을 생성해야합니다.

주석 처리의 용도는 컴파일하는 동안입니다. 2 단계 컴파일 프로세스를 권장합니다.

  1. 일반적인 방법으로 특수 효과 프로세서 및 관련 파일을 컴파일하십시오.
  2. (주석 처리를 지원하는 컴파일러 사용) 다른 파일을 컴파일하십시오. 당신은 컴파일러 일부 인수 할 수 있습니다 : 프로세서 등

경로 프로세서의 클래스 이름, 컴파일러는 annotationsroundEnv 변수를 생산하고 프로세서의 인스턴스를. (대부분의 컴파일러에서는 프로세서가 공용이고 public 생성자가 필요합니다.) 컴파일러는 process 메서드를 호출합니다.

+0

답장을 보내 주셔서 감사합니다. 따라서이 두 변수'annotations'와'roundEnv'를 구할 수있는 방법은 없습니다. –

+0

물론 annotations와 roundEnv를 얻을 수있는 방법이 있습니다. 'annotations = new HashSet (); 주석. roundEnv = new RoundEnvironment() {/ * implementation * /}'당신은 당신의 프로세서를 단위 테스트하려고합니까? 아마 조롱 프레임 워크를 사용할 수 있습니다. – emory

+0

@emory, 주석 프로세서를 단위 테스트하고 싶습니다. 그리고 이것이 첫 번째 Google 항목이므로 샘플을 환영 할 것입니다. – Snicolas