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

gsonpath.adapter.standard.extension.invalid.RemoveInvalidElementsExtension.kt Maven / Gradle / Ivy

Go to download

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

There is a newer version: 4.0.0
Show newest version
package gsonpath.adapter.standard.extension.invalid

import com.squareup.javapoet.*
import gsonpath.ProcessingException
import gsonpath.compiler.ExtensionFieldMetadata
import gsonpath.compiler.GsonPathExtension
import gsonpath.extension.RemoveInvalidElementsUtil
import gsonpath.extension.annotation.RemoveInvalidElements
import gsonpath.model.FieldInfo
import gsonpath.model.FieldType
import gsonpath.util.assign
import gsonpath.util.codeBlock
import gsonpath.util.createVariable
import javax.annotation.processing.ProcessingEnvironment
import javax.lang.model.element.Modifier

class RemoveInvalidElementsExtension : GsonPathExtension {
    override val extensionName: String
        get() = "'RemoveInvalidElements' Annotation"

    private fun verifyMultipleValuesFieldType(fieldInfo: FieldInfo): FieldType.MultipleValues {
        return when (val fieldType = fieldInfo.fieldType) {
            is FieldType.MultipleValues -> fieldType
            else -> throw ProcessingException("@RemoveInvalidElements can only be used with arrays and collections",
                    fieldInfo.element)
        }
    }

    override fun canHandleFieldRead(
            processingEnvironment: ProcessingEnvironment,
            extensionFieldMetadata: ExtensionFieldMetadata): Boolean {

        val (fieldInfo) = extensionFieldMetadata
        if (fieldInfo.getAnnotation(RemoveInvalidElements::class.java) == null) {
            return false
        }

        verifyMultipleValuesFieldType(fieldInfo)

        return true
    }

    override fun createCodeReadResult(
            processingEnvironment: ProcessingEnvironment,
            extensionFieldMetadata: ExtensionFieldMetadata,
            checkIfResultIsNull: Boolean): GsonPathExtension.ExtensionResult {

        val (fieldInfo, variableName) = extensionFieldMetadata

        val multipleValuesFieldType = verifyMultipleValuesFieldType(fieldInfo)
        val rawTypeName = TypeName.get(multipleValuesFieldType.elementTypeMirror)

        return GsonPathExtension.ExtensionResult(codeBlock {
            val typeName = fieldInfo.fieldType.typeName
            when (multipleValuesFieldType) {
                is FieldType.MultipleValues.Array -> {
                    val assignment = "\$T.removeInvalidElementsArray(\$T.class, mGson, in, \$L)"
                    val arrayFuncType = createCreateArrayFuncTypeSpec(rawTypeName)
                    if (checkIfResultIsNull) {
                        createVariable(typeName, variableName, assignment, UTIL_CLASS_NAME, rawTypeName, arrayFuncType)
                    } else {
                        assign(variableName, assignment, UTIL_CLASS_NAME, rawTypeName, arrayFuncType)
                    }
                }
                is FieldType.MultipleValues.Collection -> {
                    val assignment = "\$T.removeInvalidElementsList(\$T.class, mGson, in)"
                    if (checkIfResultIsNull) {
                        createVariable(typeName, variableName, assignment, UTIL_CLASS_NAME, rawTypeName)
                    } else {
                        assign(variableName, assignment, UTIL_CLASS_NAME, rawTypeName)
                    }
                }
            }
        })
    }

    /**
     * Required to allow converting the list into an array.
     * Type erasure is fun!
     */
    private fun createCreateArrayFuncTypeSpec(arrayType: TypeName): TypeSpec {
        val functionClassName = ClassName.get(RemoveInvalidElementsUtil.CreateArrayFunction::class.java)
        return TypeSpec.anonymousClassBuilder("")
                .addSuperinterface(ParameterizedTypeName.get(functionClassName, arrayType))
                .addMethod(MethodSpec.methodBuilder("createArray")
                        .addAnnotation(Override::class.java)
                        .addModifiers(Modifier.PUBLIC)
                        .returns(ArrayTypeName.of(arrayType))
                        .addStatement("return new \$T[0]", arrayType)
                        .build())
                .build()
    }

    private companion object {
        private val UTIL_CLASS_NAME = ClassName.get(RemoveInvalidElementsUtil::class.java)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy