Java 注释处理器与其他注释处理器创建的注释处理编辑文件
Java annotation processing edit file created by annotation processer with other annotation processor
我正在尝试通过 Java 8 中的编译时注释处理为我的源代码生成一个配置文件。
据我了解 getSupportedAnnotationTypes
class 中列出的每个注释,处理器被调用一次。
@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:如何让我的注释处理器编辑由另一个注释处理器生成的文件?
好吧,在研究 Filer
和 FileObject
的源代码数小时后,我找到了解决方案/解决方法。
为了能够访问 JavacFiler
,您需要有 com.sun.tools 作为依赖项。
将 Filer
向下转换为 JavacFiler
以访问更多方法。
文件管理器有一个 createResource(...)
和一个 getResource(...)
方法,它们似乎做同样的事情,但不同之处在于 createResource(...)
打开一个 FileObject
只用于写入,而 getResource(...)
仅供阅读。
因此,要能够从另一个 Annotation Processor 编辑文件,您必须这样做:
- 以只读方式打开文件
- 读取文件内容
- 关闭文件
- 以只写方式重新打开文件
- 将旧内容写入其中
- 添加更多数据
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。
我正在尝试通过 Java 8 中的编译时注释处理为我的源代码生成一个配置文件。
据我了解 getSupportedAnnotationTypes
class 中列出的每个注释,处理器被调用一次。
@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:如何让我的注释处理器编辑由另一个注释处理器生成的文件?
好吧,在研究 Filer
和 FileObject
的源代码数小时后,我找到了解决方案/解决方法。
为了能够访问 JavacFiler
,您需要有 com.sun.tools 作为依赖项。
将 Filer
向下转换为 JavacFiler
以访问更多方法。
文件管理器有一个 createResource(...)
和一个 getResource(...)
方法,它们似乎做同样的事情,但不同之处在于 createResource(...)
打开一个 FileObject
只用于写入,而 getResource(...)
仅供阅读。
因此,要能够从另一个 Annotation Processor 编辑文件,您必须这样做:
- 以只读方式打开文件
- 读取文件内容
- 关闭文件
- 以只写方式重新打开文件
- 将旧内容写入其中
- 添加更多数据
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。