2012-05-12 26 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)); 
    } 
} 

आप setProcessors का कॉल निकालना है तो यह एनोटेशन प्रोसेसर पर स्वचालित रूप से META-INF/services/javax.annotation.processing.Processor फ़ाइलों के आधार पर पहचान करेगा classpath।

3

यह my answer to a similar question का एक लिंक है।

आप अपने प्रश्न में सुझाए गए तरीके से एनोटेशन प्रोसेसिंग कर सकते हैं, लेकिन आपको किसी भी तरह annotations और roundEnv का उत्पादन करना होगा।

एनोटेशन प्रोसेसिंग का इच्छित उपयोग संकलन के दौरान होता है। मैं एक दो कदम संकलन प्रक्रिया की सलाह देते हैं।

  1. अपने एनोटेशन प्रोसेसर और संबंधित फ़ाइलों को सामान्य तरीके से संकलित करें।
  2. अन्य फ़ाइलों को संकलित करें (एनोटेशन प्रोसेसिंग का समर्थन करने वाले एक कंपाइलर का उपयोग करके)। आप संकलक करने के लिए कुछ तर्क करना पड़ सकता है: प्रोसेसर पथ, प्रोसेसर के वर्ग के नाम, आदि

संकलक annotations और roundEnv चर का उत्पादन करेगा और अपने प्रोसेसर का एक उदाहरण। (अधिकांश कंप्यूटर्स की आवश्यकता होती है कि आपका प्रोसेसर सार्वजनिक हो और सार्वजनिक कन्स्ट्रक्टर हो।) कंपाइलर तब process विधि का आह्वान करेगा।

+0

उत्तर के लिए धन्यवाद। तो इन दो चर 'एनोटेशन' और 'roundEnv' प्राप्त करने का कोई तरीका नहीं है? –

+0

बेशक 'एनोटेशन' और 'राउंडएएनवी' पाने का एक तरीका है। 'एनोटेशन = नया हैशसेट (); एनोटेशन जोड़ें (/ * अपनी एनोटेशन * /); 'और' roundEnv = नया RoundEnvironment() {/ * कार्यान्वयन * /} 'क्या आप अपने प्रोसेसर को यूनिट-टेस्ट करने का प्रयास कर रहे हैं? आप शायद एक मॉकिंग फ्रेमवर्क का उपयोग कर सकते हैं। – emory

+0

@emory, मैं इकाई को एनोटेशन प्रोसेसर का परीक्षण करना चाहता हूं। और एक नमूना स्वागत किया जाएगा क्योंकि यह पहली Google प्रविष्टि है। – Snicolas