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

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

There is a newer version: 4.0.0
Show 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,
    val companionObjectInstance: Any
) : ValueCreator() {
    val instanceParameter: KParameter = callable.instanceParameter!!

    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