Created
April 7, 2020 16:53
-
-
Save tschuchortdev/ba0b79dfc3abd13a34e15577e0a959b1 to your computer and use it in GitHub Desktop.
getAnnotationsByType
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
override fun <A : Annotation> getAnnotationsByType(annotationType: Class<A>): Array<out A> { | |
require(annotationType.isAnnotation) { "Not an annotation type: $annotationType" } | |
/* If the annotation class we are interested in is repeatable, then the annotation class must itself | |
be annotated with the java.lang.annotation.Repeatable meta-annotation. For the repeatable annotation class | |
there must be another annotation class whose property is an array of the repeatable annotation. Example: | |
``` | |
@Repeatable(value = Foos::class) | |
annotation class Foo // Foo is the contained class | |
annotation class Foos(val value: Array<Foo>) // Foos is the container class | |
``` | |
*/ | |
val repeatableAnn = annotationClass.getAnnotation(java.lang.annotation.Repeatable::class.java) | |
if (repeatableAnn == null) { | |
// In case it's not a repeatable annotation, just wrap the single annotation in | |
// an array if it exists | |
@Suppress("UNCHECKED_CAST") | |
return (getAnnotation<A>(annotationClass)?.let { arrayOf<Any>(it) } ?: emptyArray<Any?>()) as Array<out A> | |
} | |
else { | |
// It is indeed a repeatable annotation. The containerClass is the class of the annotation | |
// that contains the array with multiple instances of the annotationClass we are interested in | |
val containerClass = repeatableAnn.value.java | |
annotationMirrors_.flatMap { annotationMirror -> | |
when (annotationMirror.annotationType.descriptor) { | |
annotationClass.descriptorString() -> { | |
listOf(annotationMirror) | |
} | |
containerClass.descriptorString() -> { | |
(annotationMirror.elementValues.toList() | |
.single { (method, _) -> method.simpleName.toString() == "value" } | |
.second.value as Array<out AnnotationValue>) | |
.map { | |
createAnnotationProxy<A>(it.value as AnnotationMirror, annotationClass) | |
} | |
} | |
else -> { | |
emptyList<A>() | |
} | |
} | |
}.toTypedArray() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment