簡體   English   中英

注釋處理器與其他注釋處理器創建的Java注釋處理編輯文件

[英]Java annotation processing edit file created by annotation processer with other annotation processor

我正在嘗試通過 Java 8 中的編譯時注釋處理為我的源代碼生成一個配置文件。

據我了解,對於getSupportedAnnotationTypes類中列出的每個注釋,處理器都會被調用一次。

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> set = new LinkedHashSet<>();
        set.add(MCPlugin.class.getCanonicalName());
        set.add(MCAPIVersion.class.getCanonicalName());
        set.add(MCAuthor.class.getCanonicalName());
        set.add(MCAPIVersion.class.getCanonicalName());
        set.add(MCDepend.class.getCanonicalName());
        set.add(MCLoad.class.getCanonicalName());
        set.add(MCLoadBefore.class.getCanonicalName());
        set.add(MCSoftDepend.class.getCanonicalName());
        set.add(MCCommand.class.getCanonicalName());

        return set;
    }

實際上,我不想用一個注釋處理器處理所有這些注釋(這是正確的方法嗎?),因為它會導致MCCommand注釋出現問題。 所以我的計划是創建另一個注釋處理器,它只處理MCCommand注釋。

我的問題是,兩個處理器的輸出應該進入同一個輸出文件。 (這甚至可能嗎?)

我已經嘗試過像這樣重新打開資源文件(這也是我首先打開它的方式):

FileObject file = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "config.yml");

這只會產生錯誤或覆蓋現有文件。

TlDr:如何讓我的注釋處理器編輯另一個注釋處理器生成的文件?

好的,經過數小時瀏覽FilerFileObject的源代碼后,我找到了解決方案/解決方法。

為了能夠訪問JavacFiler ,您需要將 com.sun.tools 作為依賴項。

Filer向下轉換為JavacFiler以訪問更多方法。 文件管理器有一個createResource(...)和一個getResource(...)方法,它們似乎做同樣的事情,但不同之處在於createResource(...)打開一個FileObject僅用於寫入,而getResource(...)僅供閱讀。

因此,為了能夠從另一個注釋處理器編輯文件,您必須執行以下操作:

  1. 以只讀方式打開文件
  2. 讀取文件內容
  3. 關閉文件
  4. 以只寫方式重新打開文件
  5. 將舊內容寫入其中
  6. 添加更多數據
FileObject jfo = filer.getResource(StandardLocation.SOURCE_OUTPUT, "", "test.txt");
String msg = TUtils.JFOToString(jfo);    // Reads FileObject as String
jfo.delete();

jfo = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "test.txt");
TUtils.writeJFO(jfo, msg + "Hallo ich bin Processor 2");    // Writes String to FileObject
filer.close();

這感覺就像一個黑客,但我似乎工作。

我知道這是舊的,但它可能會幫助其他人。

您可以識別文件路徑並將其作為普通文件進行編輯(刪除、截斷、追加...)。

在此過程中,如果文件不存在,則會創建該文件。 但內容不會被刪除。

    public Path createIdentifyResource(String file) throws IOException {
        try {
            FileObject fileObject = processingEnv.getFiler().getResource(StandardLocation.SOURCE_OUTPUT,
                    "", file);
            return new File(fileObject.toUri()).toPath();
        } catch (IOException e) {
            FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT,
                    "", file);
            return new File(fileObject.toUri()).toPath();
        }
    }

過程很簡單。 首先嘗試獲取資源,就好像它存在一樣。 如果失敗,它將嘗試創建資源。 最后,獲取 URI 並將其轉換為 Path。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM