Reputation: 151
I am trying to generate a config file for my sourcecode via compiletime annotation processing in Java 8.
As far as I understand for each Annotation listed in the getSupportedAnnotationTypes
class, the processor gets called once.
@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;
}
Actually I don't want to process all those annotations with one annotation processer (Would this be the right way?) because it causes problems with the MCCommand
annotation.
So my plan was to create another annotation processer, which only processes the MCCommand
annotations.
My problem is, that the output of both processers should go into the same output file. (Is that even possible?)
I have already tried to reopen the resource file like this (this is also how I open it in the first place):
FileObject file = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "config.yml");
which will only create an error or override the existing file.
TlDr: How can I make my annotation processer edit a file generated by another annotation processor?
Upvotes: 3
Views: 1937
Reputation: 51
I know this is old, but it might help other people.
You can identify the file path and edit it as normal file (delete, truncate, append...).
In the process, the file will be created if it does not exist. But the content will not be deleted.
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();
}
}
The process is simple. First try to get the resource as if it exists. If it fails, it will attempt to create the resource. Finally, get the URI and convert it to Path.
Upvotes: 4
Reputation: 151
Okay, after hours of going through the sourcecode of the Filer
and the FileObject
I found a solution / workaround.
To be able to get access to the JavacFiler
you need to have com.sun.tools as dependency.
Downcast the Filer
to a JavacFiler
to get access to more methods.
The filer has a createResource(...)
and a getResource(...)
method, which seem to do the same but the difference is that createResource(...)
opens a FileObject
for writing only and the getResource(...)
for reading only.
So to be able to edit a file from another Annotation Processor you have to do:
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();
This feels like a hack, but I seems to work.
Upvotes: 2