2013-05-07 11 views
5

Ich verstehe nicht, wie ich die Enum-Werte in einem Annotationsprozessor abrufen kann.Annotationsprozessor: Alle Enum-Werte aus einem TypeMirror oder TypeElement abrufen

Meine Anmerkung ist eine benutzerdefinierte Java Bean Validation Anmerkung:

@StringEnumeration(enumClass = UserCivility.class) 
    private String civility; 

Auf meinem Annotation-Prozessor, kann ich auf Instanzen von diesem Zugang:

javax.lang.model.element.AnnotationValue 
javax.lang.model.type.TypeMirror 
javax.lang.model.element.TypeElement 

Ich weiß, es enthält die Daten über meine Enum seit ich das im Debug-Modus sehen kann. Ich sehe auch ElementKind == Enum

Aber ich möchte alle Namen für diese Enum bekommen, kann mir bitte jemand helfen.


Edit: Ich habe keinen Zugriff auf das Klassenobjekt dieser Enum, weil wir in einer Anmerkung Prozessor sind, und nicht in standart Java Reflexion Code. Also kann ich nicht Class#getEnumConstants() oder EnumSet.allOf(MyEnum.class) aufrufen, wenn Sie mir sagen, wie ich das Klassenobjekt von den oben genannten Typen erhalten kann.

+0

jemand eine Idee? –

Antwort

4

ich eine Lösung gefunden (diese verwendet Guava):

class ElementKindPredicate<T extends Element> implements Predicate<T> { 
    private final ElementKind kind; 
    public ElementKindPredicate(ElementKind kind) { 
     Preconditions.checkArgument(kind != null); 
     this.kind = kind; 
    } 
    @Override 
    public boolean apply(T input) { 
     return input.getKind().equals(kind); 
    } 
} 

private static final ElementKindPredicate ENUM_VALUE_PREDICATE = new ElementKindPredicate(ElementKind.ENUM_CONSTANT); 

public static List<String> getEnumValues(TypeElement enumTypeElement) { 
    Preconditions.checkArgument(enumTypeElement.getKind() == ElementKind.ENUM); 
    return FluentIterable.from(enumTypeElement.getEnclosedElements()) 
     .filter(ENUM_VALUE_PREDICATE) 
     .transform(Functions.toStringFunction()) 
     .toList(); 
} 
+0

Wenn jemand versucht, dies mit Eclipse zu tun, gibt es einen [Bug] (https://bugs.eclipse.org/bugs/show_bug.cgi?id=357494), der alle Felder verursacht in Ihrer enum, um 'ElementKind.ENUM_CONSTANT' von' getKind() 'zurückzugeben. – Alex

+0

Für mich scheint der funktionale Stil ohne Verschlüsse nicht sehr hilfreich zu sein. Umschreiben Sie Ihren Code in einem traditionellen Stil macht es: 'Liste Werte = neue ArrayList <>(); für (Elementelement: type.getEnclosedElements()) if (element.getKind() == ENUM_CONSTANT) values.add (element.getSimpleName(). ToString()); Rückgabewerte; ' –

-1

Hier ist ein komplettes Beispiel. Beachten Sie die Verwendung von getEnumConstants für die Enum-Werte.

public class Annotate { 

    public enum MyValues { 
     One, Two, Three  
    }; 

    @Retention(RetentionPolicy.RUNTIME) 
    public @interface StringEnumeration { 
     MyValues enumClass();   
    } 

    @StringEnumeration(enumClass = MyValues.Three) 
    public static String testString = "foo"; 

    public static void main(String[] args) throws Exception { 

     Class<Annotate> a = Annotate.class; 
     Field f = a.getField("testString"); 
     StringEnumeration se = f.getAnnotation(StringEnumeration.class); 
     if (se != null) { 
      System.out.println(se.enumClass()); 

      for(Object o : se.enumClass().getClass().getEnumConstants()) { 
       System.out.println(o); 
      } 

     }         
    } 
} 

Dies ausdrucken:

Three 
One 
Two 
Three 
+0

Wie erwähnt, habe ich keinen Zugriff auf das Klassenobjekt. Wenn ich mir bitte sagen kann wie :) –

Verwandte Themen