I'm building an Annotation Processor for Android (for the sake of future explanations, let's call it TestProcessor
).
The plan is for the processor to operate in two modes:
Mode 1
: Generation of the code A
Mode 2
: Generation of the code A
and B
Mode 2
should be only selected if the additional (optional) package exists in the environment for which the processor generates code.
Is there a way to find out in the Annotation Processor's process
method if the optional package exists?
EDIT 1:
Small clarification on the "(optional) package". By the additional package I mean a java package that may but does not have to exist in the project (that is using the processor). The optional package can for example represent the contents an external library. The external library can but does not have to be included in the project.
Let me just make a small example:
Sample
.Sample
is using my TestProcessor
.Square's
Picasso
as an example of an external librarySample
HAS Square's
Picasso
as one of its dependencies, TestProcessor
operates in Mode 2
and generates code A
and B
. In other words: if you can use classes from com.square.picasso
(in Sample
) without any problems, then processor should operate in Mode 2
.Square's
Picasso
in Sample's
dependencies, TestProcessor
operates in Mode 1
and generates only code A
.EDIT 2:
I thought of two workarounds for this problem:
processor
Modes
(example: @DoStuffModeOne
, @DoStuffModeTwo
)Application
) that triggers the usage of Mode 2
(example: @TriggerModeTwo
)For my case the second workaround is much more preferable, but is still much worse than it would be if the TestProcessor
itself could decide which Mode
to choose.
You could do a check for one of the ButterKnife
classes in the classpath of the application. Then perform your logic based on the check's result.
Class butterKnifeClass = null;
try {
butterKnifeClass = Class.forName("butterknife.ButterKnife");
} catch (ClassNotFoundException e) {
// no butterknife present
}
if (butterKnifeClass != null) {
// blah... stuff with butterknife
}
You could use this code to find out if a class is present in the annotation processing environment.
TypeElement typeElement = processingEnvironment.getElementUtils().
getTypeElement("com.squareup.picasso.Picasso");
I didn't have success using the Elements.getPackageElement()
method because it returned successfully for non-existent packages (at least under Eclipse), and running the PackageElement.getEnclosedElements()
method on packages created like this was empty even for non-empty packages. I'd suggest you go for a specific class in your package of interest as in my prior example because it worked as expected for existing type elements and returning null
for non-existing types.
I currently didn't find an Annotation Processing API based method to decide whether the type element found in this way is based on a source code file on the source path of your project or a binary class file on the compilation classpath. There could be a method for this involving the processingEnvironment.getFiler().getResource(StandardLocation.SOURCE_PATH, ...)
but, unfortunately is not portable, because StandardLocation.SOURCE_PATH
is not supported in Eclipse.
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With