I implement an annotation processor to make sure that elements marked with annotation are instances of a class that implements a specific interface, or that use types that implement a specific interface:
@Documented @Target(value = { ElementType.PARAMETER, ElementType.TYPE_USE }) @Retention(value = RetentionPolicy.RUNTIME) public @interface AuditSubject { } public interface Auditable {
For annotated items, a journal entry must be created after the method is executed (using AOP). Examples:
@CreateLogEntry public Result persist(@AuditSubject Report newReport) { // A log entry must be created based on the incoming 'newReport' instance. } @CreateLogEntry public UpdateResult<@AuditSubject Report> update(Report update) { // A log entry must be created based on the updated report, which is not the same instance as 'update' but an equivalent one. } @CreateLogEntry public Result persistBatch(List<@AuditSubject Report> batch) { // A log entry must be created for each element in 'batch' after this method execution. }
Journal entries must be created provided that Report implements Auditable ; if it is not, a runtime exception is thrown (Yikes, I forgot to implement the interface!). In this way, the annotation processor helps catch programmer errors during compilation. So far, I have successfully tested all uses in parameters, but not in the use of types. The corresponding code from the annotation processor is as follows:
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element annotated : roundEnv.getElementsAnnotatedWith(AuditSubject.class)) { // Only prints elements with ElementKind.PARAMETER)! this.messager.printMessage(Kind.NOTE, TextUtils.replaceParams("annotated: {} ; Kind : {} ; enclosing : {}", annotated, annotated.getKind(), annotated.getEnclosingElement())); if (annotated.getKind() == ElementKind.PARAMETER) { // Code here works as expected, raises errors for annotated parameters of classes that don't implement Auditable. } else if (annotated.getKind() == ElementKind.WHAT_TO_USE) { // What ElementKind do I need to use here? } } return false; }
ElementKind.PARAMETER only annotated elements with the view ElementKind.PARAMETER (the first line in the process loop () prints only one line for 'newReport' ). How can I verify that annotated types implement Auditable ? There is no constant " ElementKind.TYPE_USE " to use. I could not find any relevant information on this. Thank you for attention.
source share