2 Replies Latest reply: Jun 6, 2010 6:32 PM by 843793 RSS

    Is it possible to enclose top-level types in an annotated PackageElement?


      I'm trying to create a package-level annotation that will look into the types for further information. In general, I want to do this:

      1. Annotate a package:
      /** package-info.java */
      2. Create a class with a related annotation:
      package example.package.ExampleClass
      public class ExampleClass {
      3. Be able to get the class from the package within the AbstractProcessor implementation:
      package com.test.annotation.processor;
      import java.util.Set;
      import javax.annotation.processing.AbstractProcessor;
      import javax.annotation.processing.RoundEnvironment;
      import javax.annotation.processing.SupportedAnnotationTypes;
      import javax.annotation.processing.SupportedSourceVersion;
      import javax.lang.model.SourceVersion;
      import javax.lang.model.element.Element;
      import javax.lang.model.element.TypeElement;
      import javax.lang.model.util.ElementFilter;
      import example.package.PackageAnnotation
       * The annotation processor for all annotations defined in this project.
      @SupportedAnnotationTypes( { "example.package.PackageAnnotation",
                "example.package.ClassAnnotation" })
      public class TestAnnotationProcessor extends AbstractProcessor {
            * {@inheritDoc}
           public final boolean process(final Set<? extends TypeElement> annotations,
                     final RoundEnvironment roundEnv) {
            * {@inheritDoc}
           public final boolean process(final Set<? extends TypeElement> annotations,
                     final RoundEnvironment roundEnv) {
                Set<? extends Element> annotatedPackages = roundEnv.getElementsAnnotatedWith(PackageAnnotation.class);
                System.out.println("Number of contained elements in package: "
                     + annotatedPackages.iterator().next().getEnclosedElements().size());
                return true; /* All supported annotations are claimed by this processor. */
      I would like the System.out call to return 1. Right now, it returns 0, i.e., the classes are not loaded as being enclosed in the package. The API predicts this, on some level, by stating (for _RoundEnvironment.getElementsAnnotatedWith(Class)_):
      "Elements in a package are not considered included simply because a package-info file for that package was created."
      My question is: can I somehow include the top-level elements in the package? If I look for types annotated with @ClassAnnotation in the round environment, I can find them, but it's not nearly as elegant.
        • 1. Re: Is it possible to enclose top-level types in an annotated PackageElement?

          I'm not entirely clear what you are trying to do in terms of sequencing.

          If you want to take an annotated package-info file and based on that information create a source file in the same package, those new source files will not show up as being members of the package on that same round (in the javac implementation). A fresh PackageElement on a subsequent round will be needed.

          If the files you want to process are not passed in on the command line or create by a previous round of processing, you will need to look for them using other mechanisms.
          • 2. Re: Is it possible to enclose top-level types in an annotated PackageElemen
            Hi, thanks for the reply. Let me clarify. This is my starting state:

            1. I have an annotated package.
            2. I have one or more annotated classes in that package.

            All these annotations are related. Every time I find an annotated package, I want to look inside it for annotated classes and generate some code based on the annotations in the package and the classes.

            Right now, if I get all types annotated with the package annotation from the RoundEnvironment object, packageElement.getEnclosedTypes() returns an empty set, even if there are classes in the package.

            If I try the converse, and get the annotated classes, calling typeElement.getEnclosingTypes() does, in fact, return the package.

            Because the generated file will be generated on a per-package basis, it is really much more convenient to get the packages and obtain the classes from them; however, I can't seem to get the classes to return.

            I hope that clarifies the problem. Basically, it boils down to this:

            What do I need to do to get a non-empty set from packageElement.getEnlosedTypes()?