2012-12-03 15 views
17

के साथ कोड प्रतिस्थापन मैं कक्षा पर विधियों और फ़ील्ड डालने के लिए annotation processor लिखने की कोशिश कर रहा हूं ... और दस्तावेज़ीकरण इतना अस्पष्ट है। मैं दूर नहीं जा रहा हूं और मुझे नहीं पता कि मैं इसे सही तरीके से देख रहा हूं या नहीं।एक एनोटेशन प्रोसेसर

प्रसंस्करण वातावरण Filer ऑब्जेक्ट प्रदान करता है जिसमें नए स्रोत और कक्षा फ़ाइलों को बनाने के लिए आसान तरीके हैं। वे ठीक काम करते हैं लेकिन फिर मैंने यह पता लगाने की कोशिश की कि मौजूदा स्रोत फ़ाइलों को कैसे पढ़ा जाए, और यह सब कुछ "getResource" प्रदान करता है। तो मेरी प्रोसेसर कार्यान्वयन में मैं इस किया है:

@Override 
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 
    try { 
     for (TypeElement te : annotations) { 
      for (Element element : roundEnv.getElementsAnnotatedWith(te)) { 
       FileObject in_file = processingEnv.getFiler().getResource(
        StandardLocation.SOURCE_PATH, "", 
        element.asType().toString().replace(".", "/") + ".java"); 

       FileObject out_file = processingEnv.getFiler().getResource(
        StandardLocation.SOURCE_OUTPUT, "", 
        element.asType().toString().replace(".", "/") + ".java"); 

       //if (out_file.getLastModified() >= in_file.getLastModified()) continue; 

       CharSequence data = in_file.getCharContent(false); 

       data = transform(data); // run the macro processor 

       JavaFileObject out_file2 = processingEnv.getFiler().createSourceFile(
        element.asType().toString(), element); 
       Writer w = out_file2.openWriter(); 
       w.append(data); 
       w.close(); 
      } 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
     processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage()); 
    } 
    return true; 
} 

मेरी पहली उलझन मुझे लगता है कि element.asType().toString().replace(".", "/") + ".java" (योग्य प्रकार का नाम मिलता है और यह एक पैकेज और स्रोत फ़ाइल पथ में कन्वर्ट करने के लिए) नहीं लग रहा है मदद नहीं कर सकता है समस्या से संपर्क करने का एक अच्छा तरीका है। बाकी एपीआई इतनी अधिक इंजीनियर है लेकिन मूल स्रोत कोड को पुनर्प्राप्त करने के लिए एक आसान तरीका प्रतीत नहीं होता है।

असली समस्या यह है कि तब संकलक आउटपुट निर्देशिका ("त्रुटि: डुप्लिकेट क्लास") में दूसरी स्रोत फ़ाइल द्वारा स्वचालित रूप से परेशान हो जाता है और अब मैं अटक गया हूं।

मैंने पहले से ही यह बाकी लिखा है - कुछ डेटा की गणना करने और फ़ील्ड मानों और विधियों को सम्मिलित करने के लिए मैक्रो लेक्सर और पार्सर और व्हाट्नॉट - लेकिन यह कंपाइलर के बाहर प्रारंभिक चरण के रूप में कार्य करता है। इस तथ्य को छोड़कर कि मूल फ़ाइलों में .java एक्सटेंशन नहीं हो सकता है (उन्हें देखकर संकलक को रोकने के लिए), यह अच्छी तरह से काम करता है। तब मैंने सुना कि एनोटेशन कोड पीढ़ी कर सकते हैं, जो मुझे लगता है कि यह अधिक उचित और सुविधाजनक होगा, लेकिन मुझे इसके बारे में ज्यादा मार्गदर्शन नहीं मिल रहा है।

+1

देखें: http://techbitsfromsridhar.blogspot.ca/2013/02/java-compiler-plug-ins-in-java-8-use.html –

उत्तर

16

एनोटेशन प्रोसेसर के पीछे इरादा एक डेवलपर को मौजूदा कक्षाओं को प्रतिस्थापित न करने के लिए नए वर्ग जोड़ने की अनुमति देना है। ऐसा कहा जा रहा है कि एक बग है जो आपको मौजूदा कक्षाओं में कोड जोड़ने की अनुमति देती है। Project Lombok में आपके संकलित जावा कक्षाओं में गेटर और सेटर (अन्य चीजों के साथ) जोड़ने के लिए leveraged है।

जिस तरीके से मैंने 'प्रतिस्थापन' विधियों/फ़ील्ड को ले लिया है, या तो इनपुट कक्षा में विस्तार या प्रतिनिधि है। यह आपको लक्ष्य वर्ग में कॉल ओवरराइड/डायल करने की अनुमति देता है।

तो अगर यह आपके इनपुट वर्ग है:

InputImpl.java:

InputReplacementImpl.java:

public class InputReplacementImpl implmements Input{ 

    private Input delegate; 

    //setup delegate.... 

    public void foo(){ 
     System.out.println("foo replacement"); 
    } 
    public void bar(){ 
     delegate.bar(); 
    } 
} 

public class InputImpl implmements Input{ 
    public void foo(){ 
     System.out.println("foo"); 
    } 
    public void bar(){ 
     System.out.println("bar"); 
    } 
} 

आप "की जगह" करने के लिए इसे निम्नलिखित उत्पन्न कर सकता है

यह सवाल पूछता है, आप InputReplacementImpl इन्स का संदर्भ कैसे देते हैं InputImpl की टीड। आप या तो रैपिंग करने के लिए कुछ और कोड उत्पन्न कर सकते हैं या जेनरेट होने की उम्मीद वाले कोड के कन्स्ट्रक्टर को कॉल कर सकते हैं।

मुझे सच में यकीन नहीं है कि आपका प्रश्न क्या है, लेकिन मुझे आशा है कि यह आपके मुद्दों पर कुछ प्रकाश डालेगा।

+0

* आह हा! * मुझे लगता है कि मैंने पहले लॉमोक देखा था, और यह आंशिक रूप से क्यों था कि मुझे यह सोचने का कोई कारण नहीं था कि यह असंभव था। यह उत्तर संकलक त्रुटि बताता है और मुझे कुछ विकल्प देता है। मुझे एएसटी हैक्स में फेंकने की कोई इच्छा नहीं है, वर्तमान में, सरल regexps कोड ढूंढने और मेरे लिए प्रतिस्थापित करने के लिए करते हैं। कक्षा में प्रतिनिधि मेरे मामले में वास्तव में करने योग्य नहीं है क्योंकि मूल वर्ग पूर्ण और संकलित नहीं है।जहां तक ​​मैं देखता हूं, एनोटेशन एपीआई की यह मूर्खतापूर्ण छोटी सीमा का मतलब है कि इसकी जटिलता के बावजूद यह मेरे लिए उपयोगी नहीं है। लेकिन अब मुझे पता है कि क्या करना है: एनोटेशन का उपयोग न करें! आपकी मदद के लिए बहुत बहुत शुक्रिया। – Boann

+0

निश्चित बात @ बॉन, आपकी परियोजना के साथ शुभकामनाएं। –

संबंधित मुद्दे