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

com.fasterxml.jackson.module.kotlin.MethodValueCreator.kt Maven / Gradle / Ivy

Go to download

Add-on module for Jackson (https://github.com/FasterXML/jackson/) to support Kotlin language, specifically introspection of method/constructor parameter names, without having to add explicit property name annotation.

The newest version!
package com.fasterxml.jackson.module.kotlin

import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.extensionReceiverParameter
import kotlin.reflect.full.instanceParameter
import kotlin.reflect.jvm.isAccessible

internal class MethodValueCreator private constructor(
    override val callable: KFunction,
    override val accessible: Boolean,
    companionObjectInstance: Any
) : ValueCreator() {
    override val bucketGenerator: BucketGenerator = callable.parameters.let {
        BucketGenerator.forMethod(it.size, it[0], companionObjectInstance)
    }

    companion object {
        fun  of(callable: KFunction): MethodValueCreator? {
            // we shouldn't have an instance or receiver parameter and if we do, just go with default Java-ish behavior
            if (callable.extensionReceiverParameter != null) return null

            val possibleCompanion = callable.instanceParameter!!.type.erasedType().kotlin

            // abort, we have some unknown case here
            if (!possibleCompanion.isCompanion) return null

            // To prevent the call from failing, save the initial value and then rewrite the flag.
            val initialCallableAccessible = callable.isAccessible
            if (!initialCallableAccessible) callable.isAccessible = true

            val (companionObjectInstance: Any, accessible: Boolean) = try {
                // throws ex
                val instance = possibleCompanion.objectInstance!!

                // If an instance of the companion object can be obtained, accessibility depends on the KFunction
                instance to initialCallableAccessible
            } catch (ex: IllegalAccessException) {
                // fallback for when an odd access exception happens through Kotlin reflection
                possibleCompanion.java.enclosingClass.declaredFields
                    .firstOrNull { it.type.kotlin.isCompanion }
                    ?.let {
                        it.isAccessible = true

                        // If the instance of the companion object cannot be obtained, accessibility will always be false
                        it.get(null) to false
                    } ?: throw ex
            }

            return MethodValueCreator(callable, accessible, companionObjectInstance)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy