gsonpath.util.AnnotationFetcher.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gsonpath-compiler-base Show documentation
Show all versions of gsonpath-compiler-base Show documentation
An annotation processor which generates Type Adapters for the Google Gson library
package gsonpath.util
import javax.lang.model.element.AnnotationMirror
import javax.lang.model.element.Element
import javax.lang.model.element.TypeElement
import javax.lang.model.type.NoType
class AnnotationFetcher(private val typeHandler: TypeHandler, private val fieldGetterFinder: FieldGetterFinder) {
fun getAnnotation(parentElement: TypeElement, fieldElement: Element, annotationClass: Class): T? {
return fieldElement.getAnnotationEx(annotationClass)
?: findMethodAnnotation(parentElement, fieldElement, annotationClass)
}
private fun findMethodAnnotation(
parentElement: TypeElement?,
fieldElement: Element,
annotationClass: Class): T? {
return when {
parentElement != null && parentElement !is NoType -> {
fieldGetterFinder.findGetter(parentElement, fieldElement)
?.getAnnotation(annotationClass)
?: findParentMethodAnnotation(parentElement, fieldElement, annotationClass)
}
else -> null
}
}
/**
* Find the annotations from the method within superclass or interfaces.
*/
private fun findParentMethodAnnotation(
parentElement: TypeElement,
fieldElement: Element,
annotationClass: Class): T? {
val parentMirrors =
if (parentElement.interfaces.size > 0) {
listOf(parentElement.superclass).plus(parentElement.interfaces)
} else {
listOf(parentElement.superclass)
}
return parentMirrors
.asSequence()
.map { mirror ->
findMethodAnnotation(typeHandler.asElement(mirror) as? TypeElement, fieldElement, annotationClass)
}
.filterNotNull()
.firstOrNull()
}
fun getAnnotationMirrors(parentElement: TypeElement, fieldElement: Element): List {
return fieldElement.annotationMirrors
.plus(getMethodAnnotationMirrors(parentElement, fieldElement))
}
private fun getMethodAnnotationMirrors(parentElement: TypeElement?, fieldElement: Element): List {
return if (parentElement != null && parentElement !is NoType) {
val annotationMirrors = fieldGetterFinder.findGetter(parentElement, fieldElement)
?.annotationMirrors ?: emptyList()
val superElement = typeHandler.asElement(parentElement.superclass)
annotationMirrors.plus(getMethodAnnotationMirrors(superElement as? TypeElement, fieldElement))
} else {
emptyList()
}
}
}