Search code examples
javaannotations

How to get values from custom sub-annotation?


I have a question about getting custom annotation value which is value of another custom annotation. For example I have a @SqlInfo annotation interface which have two values which is also annotation interfaces.

SqlInfo.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SqlInfo {

    CodificationInfo codificationInfo();
    DocumentInfo documentInfo();
}  

@CodificationInfo and @DocumentInfo is also annotation interfaces. Each of it has his own different values.

CodificationInfo.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CodificationInfo {

    enum KEYS {
        DOMAIN,
        FILE,
        TABLE,
        CLASS
    }

    String domain() default "";
    String fileName() default "";
    String table() default "";
    Class codificationClass();
}

While I am using only @CodificationInfo annotation for the class. I am getting values from it by using this method:

Annotation values getter method

public Object getClassAnnotationValue(Class c, String key) {
    Annotation annotation = c.getAnnotation(CodificationInfo.class);
    return getObjectByKey(annotation, key);
}

private Object getObjectByKey(Annotation annotation, String key) {
    if (annotation instanceof CodificationInfo) {
        if (key.equalsIgnoreCase(CodificationInfo.KEYS.TABLE.toString())) {
            return ((CodificationInfo) annotation).table();
        } else if (key.equalsIgnoreCase(CodificationInfo.KEYS.CLASS.toString())) {
            return ((CodificationInfo) annotation).codificationClass();
        } else if (key.equalsIgnoreCase(CodificationInfo.KEYS.DOMAIN.toString())) {
            return ((CodificationInfo) annotation).domain();
        } else if (key.equalsIgnoreCase(CodificationInfo.KEYS.FILE.toString())) {
            return ((CodificationInfo) annotation).fileName();
        }
    }
    return null;
}  

I want to know how to get @CodificationInfo values while I am using @SqlInfo annotation for the class? It means - how to get values from sub-annotation?

P.S.: I know that I can use both annotations separately for the class. But I want to know the any way how to get values from sub-annotation. For example hibernate use it for @AuditOverrides annotation.


Solution

  • If you have a type declared like:

    @SqlInfo(codificationInfo = @CodificationInfo(codificationClass = AClass.class)
    public class MyType { }
    

    you can reflectively get the inner annotation values with:

    final SqlInfo sqlInfoAnnotation = (SqlInfo) c.getAnnotation(SqlInfo.class);    
    if (sqlInfoAnnotation == null) return;
    
    final CodificationInfo codInfoAnnotation = sqlInfoAnnotation.codificationInfo();
    
    final Class<?> codClass = codInfoAnnotation.codificationClass();
    

    Note: you can avoid having to cast the annotation by not using raw types (prefer Class<?> over Class).