2013-05-07 25 views
5

Nie rozumiem, w jaki sposób można pobrać wartości wyliczenia w procesorze adnotacji.Procesor adnotacji: pobierz wszystkie wartości wyliczeniowe z obiektu TypeMirror lub TypeElement

Moja adnotacja jest zwyczaj adnotacji Java Bean Validation:

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

Na mój procesor adnotacji, można uzyskać dostęp do wystąpień tych:

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

wiem, że zawiera dane o moim enum ponieważ widzę to w trybie debugowania. Też widzę ElementKind == Enum Ale chcę uzyskać wszystkie nazwiska dla tego Enum, czy ktoś może mi pomóc proszę.


Edit: nie mam dostępu do obiektu tej klasy Enum, bo jesteśmy w procesor adnotacji, a nie standardowe kodu refleksji Java. Nie mogę więc zadzwonić pod numer Class#getEnumConstants() lub EnumSet.allOf(MyEnum.class), chyba że powiesz mi, w jaki sposób mogę uzyskać obiekt klasy z wymienionych wyżej typów.

+0

ma ktoś jakiś pomysł? –

Odpowiedz

4

znalazłem rozwiązanie (ta wykorzystuje 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

Jeśli ktoś próbuje to zrobić z zaćmieniem, pojawia się błąd (https://bugs.eclipse.org/bugs/show_bug.cgi?id=357494), który powoduje, że wszystkie pola w twoim wyliczeniu, aby zwrócić 'ElementKind.ENUM_CONSTANT' z' getKind() '. – Alex

+0

Dla mnie funkcjonalny styl wydaje się mało przydatny bez zamknięć. Przepisanie kodu w tradycyjnym stylu powoduje: 'List wartości = new ArrayList <>(); dla (Element elementu: type.getEnclosedElements()) if (element.getKind() == ENUM_CONSTANT) values.add (element.getSimpleName(). ToString()); zwraca wartości; ' –

-1

Oto pełny przykład. Zwróć uwagę na użycie getEnumConstants na wartościach wyliczeniowych.

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); 
      } 

     }         
    } 
} 

ten wypisze:

Three 
One 
Two 
Three 
+0

Jak już wspomniano, nie mam dostępu do obiektu Class. Jeśli mogę, proszę, powiedz mi, jak :) –

Powiązane problemy