2 Replies Latest reply: Mar 12, 2010 8:28 AM by 843793 RSS

    Easier way to copy known elements?

    843793
      I'm processing code like the following:
      @WebService(name = "ClientInfo", targetNamespace = "http://services.foo.com/client")
      public interface ClientInfo { ... }
      and would like to copy a known subset of the element-value pairs of a known annotation to the generated code:
      @WebService(targetNamespace = "http://services.foo.com/client")
      public class ClientInfoProxy implements ClientInfo { ... }
      I have no choice about using JDK 1.5 and have implemented a processor that delegates to an interface visitor. This is the basic processing that goes on in the visitor method:
      public void visitInterfaceDeclaration(InterfaceDeclaration decl) {
          Collection<AnnotationMirror> declAnnoMirrors = decl.getAnnotationMirrors();
          for (AnnotationMirror declAnnoMirror : declAnnoMirrors) {
              AnnotationType declAnnoType = declAnnoMirror.getAnnotationType();
              AnnotationTypeDeclaration declAnnoTypeDecl = declAnnoType.getDeclaration();
              String declAnnoFullName = declAnnoTypeDecl.getQualifiedName();
              if (declAnnoFullName.equals(WebService.class.getName())) {
                  Map<AnnotationTypeElementDeclaration, AnnotationValue> declAnnoValues = declAnnoMirror.getElementValues();
                  for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> declAnnoValue : declAnnoValues.entrySet()) {
                      String name = declAnnoValue.getKey().getSimpleName();
                      if (name.equals("targetNamespace")) {
                          Object value = declAnnoValue.getValue().getValue();
                          break;
                      }
                  }
              }
              break;
          }
      }
      Which seems like a lot of work to get at a known annotation and one of its known elements. Is there something more direct that I'm missing? Thanks for any pointers!
        • 1. Re: Easier way to copy known elements?
          608410
          Since they are known annotations you could use this method on the InterfaceDeclaration.

          [http://java.sun.com/javase/6/docs/jdk/api/apt/mirror/com/sun/mirror/declaration/Declaration.html#getAnnotation(java.lang.Class)|http://java.sun.com/javase/6/docs/jdk/api/apt/mirror/com/sun/mirror/declaration/Declaration.html#getAnnotation(java.lang.Class)]

          Those API's you are currently using for accessing the bits of an annotation are wonderful for processing annotations you don't know (or care) about, but pretty horrid for known annotations.

          that is why there is the convenience forms that give you the annotation itself. But it gets tricky if the annotation members have Class or Enum types, (because then you want the compile time - not the runtime representation) so for JDK6 I've built [Prisms |https://hickory.dev.java.net/nonav/apidocs/index.html?net/java/dev/hickory/prism/package-summary.html] (partial reflections of annotations) for convenience - but that is not an option for you because it uses the newer JDK6 API.

          Bruce
          • 2. Re: Easier way to copy known elements?
            843793
            I did see that method, but my initial reading of the warnings kind of scared me off ;-). So, the idea is that I can just cast that annotation instance to be what I need and invoke a method to get an element's value? That seems easy enough - I'll give it a shot and then return with a handful of Dukes...

            Edit: For posterity, here's what the modified code looks like:
            public void visitInterfaceDeclaration(InterfaceDeclaration decl) {
                WebService wsa = decl.getAnnotation(WebService.class);
                if (wsa != null) { 
                    String tns = wsa.targetNamespace();
                }
            }
            Edited by: kschneid on Mar 12, 2010 9:23 AM