lundi 30 novembre 2015

Java - Annotation Processing

I have an annotation which marks classes that contain an inner class which implements a named interface.

Here's an example of how this annotation is used:

public interface Implementable {}

@Deserializable(Implementable.class)
public class ImplementableFactory {
    public static Implementable getImplementable() {
        return new Impl();
    }
    private class Impl implements Implementable {}
}

And here's the annotation itself:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public @interface Deserializable {
    Class value();
}

I'd like to do some annotation processing to ensure this contract. I've created an annotation processing class for that purpose:

public class DeserializableProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for(Element element : roundEnv.getElementsAnnotatedWith(Deserializable.class)){
            TypeMirror expected = getDeserializableValue(element);
            if (expected != null) {
                element.getEnclosedElements().forEach( enclosed -> {
                    if (enclosed.getKind().equals(ElementKind.CLASS)) {
                        Boolean found = false;
                        ***...?***
                        if (!found) {
                            String message = String.format("Classes marked with the Deserializable annotation must contain an inner class with implements the value of the annotation. %s does not contain a class which implements %s.",
                                    element.getSimpleName().toString(),
                                    expected.toString());
                            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message);
                        }
                    }
                });
            }
        }
        return true;
    }

    private TypeMirror getDeserializableValue(Element element) {
        ...
    }
}

At this point it simply iterates through each of the inner classes - I'm not sure how to check to see if enclosed implements expected. Can someone point me in the right direction?





Aucun commentaire:

Enregistrer un commentaire