Skip to content

Commit

Permalink
Merge pull request #45 from ProjectMapK/refactor-converters
Browse files Browse the repository at this point in the history
Refactor converters
  • Loading branch information
k163377 authored Jan 19, 2023
2 parents 03a558b + 5fa44a1 commit 0877cb3
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import com.fasterxml.jackson.databind.introspect.AnnotatedMember
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector
import com.fasterxml.jackson.module.kotlin.deser.StrictNullChecksConverter
import com.fasterxml.jackson.databind.util.Converter
import com.fasterxml.jackson.module.kotlin.deser.CollectionValueStrictNullChecksConverter
import com.fasterxml.jackson.module.kotlin.deser.MapValueStrictNullChecksConverter
import com.fasterxml.jackson.module.kotlin.deser.ValueClassUnboxConverter
import com.fasterxml.jackson.module.kotlin.deser.value_instantiator.creator.ValueParameter
import kotlinx.metadata.Flag
Expand Down Expand Up @@ -138,15 +140,15 @@ private fun ValueParameter.createValueClassUnboxConverterOrNull(rawType: Class<*
// @see com.fasterxml.jackson.module.kotlin._ported.test.StrictNullChecksTest#testListOfGenericWithNullValue
private fun ValueParameter.isNullishTypeAt(index: Int) = arguments.getOrNull(index)?.isNullable ?: true

private fun ValueParameter.createStrictNullChecksConverterOrNull(rawType: Class<*>): StrictNullChecksConverter<*>? {
private fun ValueParameter.createStrictNullChecksConverterOrNull(rawType: Class<*>): Converter<*, *>? {
@Suppress("UNCHECKED_CAST")
return when {
Array::class.java.isAssignableFrom(rawType) && !this.isNullishTypeAt(0) ->
StrictNullChecksConverter.ForArray(rawType as Class<Array<*>>, this)
CollectionValueStrictNullChecksConverter.ForArray(this)
Iterable::class.java.isAssignableFrom(rawType) && !this.isNullishTypeAt(0) ->
StrictNullChecksConverter.ForIterable(rawType as Class<Iterable<*>>, this)
CollectionValueStrictNullChecksConverter.ForIterable(this)
Map::class.java.isAssignableFrom(rawType) && !this.isNullishTypeAt(1) ->
StrictNullChecksConverter.ForMapValue(rawType as Class<Map<*, *>>, this)
MapValueStrictNullChecksConverter(this)
else -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,21 @@ package com.fasterxml.jackson.module.kotlin.deser

import com.fasterxml.jackson.databind.JavaType
import com.fasterxml.jackson.databind.type.TypeFactory
import com.fasterxml.jackson.databind.util.Converter
import com.fasterxml.jackson.databind.util.StdConverter
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
import com.fasterxml.jackson.module.kotlin.deser.value_instantiator.creator.ValueParameter

internal class ValueClassUnboxConverter<T : Any>(private val valueClass: Class<T>) : Converter<T, Any?> {
internal class ValueClassUnboxConverter<T : Any>(private val valueClass: Class<T>) : StdConverter<T, Any?>() {
private val unboxMethod = valueClass.getDeclaredMethod("unbox-impl").apply {
if (!this.isAccessible) this.isAccessible = true
}
private val outType = unboxMethod.returnType

override fun convert(value: T): Any? = unboxMethod.invoke(value)

override fun getInputType(typeFactory: TypeFactory): JavaType = typeFactory.constructType(valueClass)
override fun getOutputType(typeFactory: TypeFactory): JavaType = typeFactory.constructType(outType)
}

internal sealed class StrictNullChecksConverter<T : Any> : Converter<T, T> {
protected abstract val clazz: Class<T>
internal sealed class CollectionValueStrictNullChecksConverter<T : Any> : StdConverter<T, T>() {
protected abstract val valueParameter: ValueParameter

protected abstract fun getValues(value: T): Iterator<*>
Expand All @@ -38,27 +35,31 @@ internal sealed class StrictNullChecksConverter<T : Any> : Converter<T, T> {
return value
}

override fun getInputType(typeFactory: TypeFactory): JavaType = typeFactory.constructType(clazz)
override fun getOutputType(typeFactory: TypeFactory): JavaType = typeFactory.constructType(clazz)

class ForIterable(
override val clazz: Class<Iterable<*>>,
override val valueParameter: ValueParameter
) : StrictNullChecksConverter<Iterable<*>>() {
) : CollectionValueStrictNullChecksConverter<Iterable<*>>() {
override fun getValues(value: Iterable<*>): Iterator<*> = value.iterator()
}

class ForArray(
override val clazz: Class<Array<*>>,
override val valueParameter: ValueParameter
) : StrictNullChecksConverter<Array<*>>() {
) : CollectionValueStrictNullChecksConverter<Array<*>>() {
override fun getValues(value: Array<*>): Iterator<*> = value.iterator()
}
}

class ForMapValue(
override val clazz: Class<Map<*, *>>,
override val valueParameter: ValueParameter
) : StrictNullChecksConverter<Map<*, *>>() {
override fun getValues(value: Map<*, *>): Iterator<*> = value.values.iterator()
internal class MapValueStrictNullChecksConverter(
private val valueParameter: ValueParameter
) : StdConverter<Map<*, *>, Map<*, *>>() {
override fun convert(value: Map<*, *>): Map<*, *> = value.apply {
entries.forEach { (k, v) ->
if (v == null) {
throw MissingKotlinParameterException(
valueParameter,
null,
"A null value was entered for key $k of the parameter ${valueParameter.name}."
)
}
}
}
}

0 comments on commit 0877cb3

Please sign in to comment.