All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gsonpath.adapter.util.AdapterFactoryUtil.kt Maven / Gradle / Ivy

Go to download

An annotation processor which generates Type Adapters for the Google Gson library

The newest version!
package gsonpath.adapter.util

import com.squareup.javapoet.ClassName
import gsonpath.ProcessingException
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.Element
import javax.lang.model.element.ElementKind
import javax.lang.model.element.TypeElement

object AdapterFactoryUtil {
    inline fun  getAnnotatedModelElements(
            env: RoundEnvironment,
            annotations: Set,
            supportedElementKinds: List = listOf(ElementKind.CLASS)): Set> {

        val supportedAnnotations = getSupportedAnnotations(annotations, T::class.java)
        val customAnnotations = getCustomAnnotations(annotations, T::class.java)

        // Avoid going any further if no supported annotations are found.
        if (supportedAnnotations.isEmpty() && customAnnotations.isEmpty()) {
            return emptySet()
        }

        return addModelElements(env, customAnnotations, supportedElementKinds)
                .plus(addCustomModelElements(env, customAnnotations, supportedElementKinds))
                .toSet()
    }

    inline fun  addModelElements(
            environment: RoundEnvironment,
            customAnnotations: List,
            supportedElementKinds: List
    ): Sequence> {

        return environment
                .getElementsAnnotatedWith(T::class.java)
                .asSequence()
                .filter {
                    filterElementKind(
                            element = it,
                            supportedElementKinds = supportedElementKinds,
                            allowCustomAnnotation = true,
                            annotationReference = T::class.java)
                }
                .map {
                    ElementAndAnnotation(it as TypeElement, it.getAnnotation(T::class.java))
                }
                .filter {
                    !customAnnotations.contains(it.element)
                }
    }

    inline fun  addCustomModelElements(
            environment: RoundEnvironment,
            customAnnotations: List,
            supportedElementKinds: List
    ): List> {

        return customAnnotations.flatMap { customAnnotation ->
            environment
                    .getElementsAnnotatedWith(customAnnotation)
                    .filter {
                        filterElementKind(
                                element = it,
                                supportedElementKinds = supportedElementKinds,
                                allowCustomAnnotation = false,
                                annotationReference = customAnnotation)
                    }
                    .map {
                        ElementAndAnnotation(it as TypeElement, customAnnotation.getAnnotation(T::class.java))
                    }
        }
    }

    fun filterElementKind(
            element: Element,
            supportedElementKinds: List,
            allowCustomAnnotation: Boolean,
            annotationReference: Any
    ): Boolean {

        if (allowCustomAnnotation && element.kind == ElementKind.ANNOTATION_TYPE) {
            return false
        }

        if (!supportedElementKinds.contains(element.kind)) {
            throw ProcessingException("$annotationReference can only be used with types: [${supportedElementKinds.joinToString()}]", element)
        }

        return true
    }

    fun getSupportedAnnotations(annotations: Set, annotationClassName: Class) =
            annotations
                    .asSequence()
                    .map(ClassName::get)
                    .filter { it == ClassName.get(annotationClassName) }
                    .toList()

    fun getCustomAnnotations(annotations: Set, annotationClassName: Class) =
            annotations.filter { it.getAnnotation(annotationClassName) != null }
}

data class ElementAndAnnotation(
        val element: TypeElement,
        val annotation: T
)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy