Skip to content

Commit 5da9c4e

Browse files
committed
Merge branch '2.13' of github.com:FasterXML/jackson-module-kotlin into 2.13
2 parents 8aadaf4 + 1bc121d commit 5da9c4e

File tree

12 files changed

+328
-42
lines changed

12 files changed

+328
-42
lines changed

release-notes/CREDITS-2.x

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,125 +13,118 @@ Authors:
1313

1414
Contributors:
1515

16+
# 2.13.NEXT
17+
18+
Stefan Schmid (schmist@github)
19+
* #519: Contributed test for #518 (null should deserialize to _the_ Unit instance)
20+
1621
wrongwrong (k163377@github)
1722
* #456: Refactor KNAI.findImplicitPropertyName()
1823
* #449: Refactor AnnotatedMethod.hasRequiredMarker()
19-
(2.13.NEXT)
24+
* #521: Fixed lookup of instantiators
2025

2126
Dmitri Domanine (novtor@github)
2227
* Contributed fix for #490: Missing value of type JsonNode? is deserialized as NullNode instead of null
23-
(2.13.NEXT)
28+
29+
# 2.13.0
2430

2531
Fedor Bobin (Fuud@github)
2632
* #496, #45: Fix treeToValue extension function should not have type erasure
27-
(2.13)
2833

2934
Mikhael Sokolov (sokomishalov@github)
3035
* #489: JsonNode, ArrayNode and ObjectNode extension functions
31-
(2.13)
3236

3337
Max Wiechmann (MaxMello@github)
3438
* #494: ProGuard ProTips in the README
35-
(2.13)
3639

3740
Róbert Papp (TWiStErRob@github)
3841
* #477: KotlinFeature documentation & deprecation replacements
39-
(2.13)
4042

4143
wrongwrong (k163377@github)
4244
* #468: Improved support for value classes
43-
(2.13)
4445

4546
wrongwrong (k163377@github)
4647
* #460: Test for GitHub #451 (`-` in property name handling)
47-
(2.13)
4848

4949
wrongwrong (k163377@github)
5050
* #447: Fix edge case when dealing with sealed classes
51-
(2.13)
5251

5352
wrongwrong (k163377@github)
5453
* Contributed #438: Fixed mapping failure when `private` `companion object` is named
55-
(2.13)
54+
55+
# 2.12.5
5656

5757
Marshall Pierce (marshallpierce@github)
5858
* #474: Reported disrespect for @JsonProperty on parent class
59-
(2.12.5)
6059

6160
Christopher Mason (masoncj@github)
6261
* #194: Contributed test case for @JsonIdentityInfo usage
63-
(2.12.5)
6462

6563
Martin Häusler (MartinHaeusler@github)
6664
* Reported #194: @JsonIdentityInfo bug
67-
(2.12.5)
65+
66+
# 2.12.2
6867

6968
Eric Fenderbosch (efenderbosch@github)
7069
* Fixed #182: Serialize unsigned numbers
71-
(2.12.2)
7270

7371
Elisha Peterson (triathematician@github)
7472
* Reported #409: `module-info.java` missing "exports"
75-
(2.12.2)
73+
74+
# 2.12.1
7675

7776
Wolfgang Jung (elektro-wolle@github)
7877
* Fixed inline class serialization
79-
(2.12.1)
78+
79+
# 2.12.0
8080

8181
John Flynn (Neuman968@github)
8282
* Contributed extension methods for SimpleModule to add serializer and deserializer
8383
extension functions for KClass #322
84-
(2.12.0)
8584

8685
Mateusz Stefek (MateuszStefek@github)
8786
* Reported #321: Make MissingKotlinParameterException a descendant of MismatchedInputException
88-
(2.12.0)
8987

9088
Hideaki Tanabe (tanabe@github)
9189
* Brought README.md into the modern world of Gradle (compile -> implementation)
92-
(2.12.0)
9390

9491
Hidde Wieringa (hiddewie@github)
9592
* Contributed test case for issue 308
9693
* Contributed Kotlin DSL constructor
97-
(2.12.0)
9894

9995
David Riggleman (DavidRigglemanININ@github)
10096
* Wrote strict null checking for collection values
101-
(2.12.0)
97+
98+
# 2.11.0
10299

103100
Drew Stephens (dinomite@github)
104101
* Contributed fix for #281: KotlinObjectSingletonDeserializer fails to deserialize
105102
previously serialized JSON as it doesn't delegate deserializeWithType
106-
(2.11.0)
103+
104+
# 2.10.2
107105

108106
Patrick Strawderman (kilink@github)
109107
* Reported #279: 2.10 introduces another binary compatibility issue in `KotlinModule`
110108
constructor
111-
(2.10.2)
112109

113110
Vladimir Petrakovich (frost13it@github)
114111
* Contributed fix for #279: 2.10 introduces another binary compatibility issue in
115112
`KotlinModule` constructor
116-
(2.10.2)
113+
114+
# 2.10.1
117115

118116
Stéphane B (StephaneBg@github)
119117
* Submitted fix for #176: Version 2.9.7 breaks compatibility with Android minSdk < 24
120-
(2.10.1)
121118

122119
Alain Lehmann (ciderale@github)
123120
* Contributed fix for #225: Don't instantiate new instances of Kotlin singleton objects
124-
(2.10.1)
125121

126122
Andrey Lipatov (LipatovAndrey@github)
127123
* Contributed fix for #80: Boolean property name starting with 'is' not serialized /
128124
deserialized properly
129-
(2.10.1)
130125

131126
Konstantin Volivach (kostya05983@github)
132127
* Contributed fix for #254: Add serializers for Sequences
133-
(2.10.1)
134128

135129
Laimonas Turauskas (Laimiux@github)
136130
* Contributed fix for #180: handle nullable method parameters correctly (for creator methods)
137-
(2.10.1)

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinDeserializers.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@file:Suppress("EXPERIMENTAL_API_USAGE")
2-
31
package com.fasterxml.jackson.module.kotlin
42

53
import com.fasterxml.jackson.core.JsonParser
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.fasterxml.jackson.module.kotlin
2+
3+
import com.fasterxml.jackson.core.JsonToken
4+
import com.fasterxml.jackson.core.exc.InputCoercionException
5+
import com.fasterxml.jackson.databind.*
6+
import com.fasterxml.jackson.databind.deser.std.StdKeyDeserializer
7+
import com.fasterxml.jackson.databind.deser.std.StdKeyDeserializers
8+
9+
// The reason why key is treated as nullable is to match the tentative behavior of StdKeyDeserializer.
10+
// If StdKeyDeserializer is modified, need to modify this too.
11+
12+
internal object UByteKeyDeserializer : StdKeyDeserializer(TYPE_SHORT, UByte::class.java) {
13+
override fun deserializeKey(key: String?, ctxt: DeserializationContext): UByte? = super.deserializeKey(key, ctxt)
14+
?.let {
15+
(it as Short).asUByte() ?: throw InputCoercionException(
16+
null,
17+
"Numeric value (${key}) out of range of UByte (0 - ${UByte.MAX_VALUE}).",
18+
JsonToken.VALUE_NUMBER_INT,
19+
UByte::class.java
20+
)
21+
}
22+
}
23+
24+
internal object UShortKeyDeserializer : StdKeyDeserializer(TYPE_INT, UShort::class.java) {
25+
override fun deserializeKey(key: String?, ctxt: DeserializationContext): UShort? = super.deserializeKey(key, ctxt)
26+
?.let {
27+
(it as Int).asUShort() ?: throw InputCoercionException(
28+
null,
29+
"Numeric value (${key}) out of range of UShort (0 - ${UShort.MAX_VALUE}).",
30+
JsonToken.VALUE_NUMBER_INT,
31+
UShort::class.java
32+
)
33+
}
34+
}
35+
36+
internal object UIntKeyDeserializer : StdKeyDeserializer(TYPE_LONG, UInt::class.java) {
37+
override fun deserializeKey(key: String?, ctxt: DeserializationContext): UInt? = super.deserializeKey(key, ctxt)
38+
?.let {
39+
(it as Long).asUInt() ?: throw InputCoercionException(
40+
null,
41+
"Numeric value (${key}) out of range of UInt (0 - ${UInt.MAX_VALUE}).",
42+
JsonToken.VALUE_NUMBER_INT,
43+
UInt::class.java
44+
)
45+
}
46+
}
47+
48+
// kind parameter is dummy.
49+
internal object ULongKeyDeserializer : StdKeyDeserializer(TYPE_LONG, ULong::class.java) {
50+
override fun deserializeKey(key: String?, ctxt: DeserializationContext): ULong? = key?.let {
51+
it.toBigInteger().asULong() ?: throw InputCoercionException(
52+
null,
53+
"Numeric value (${key}) out of range of ULong (0 - ${ULong.MAX_VALUE}).",
54+
JsonToken.VALUE_NUMBER_INT,
55+
ULong::class.java
56+
)
57+
}
58+
}
59+
60+
internal object KotlinKeyDeserializers : StdKeyDeserializers() {
61+
override fun findKeyDeserializer(
62+
type: JavaType,
63+
config: DeserializationConfig?,
64+
beanDesc: BeanDescription?
65+
): KeyDeserializer? = when (type.rawClass) {
66+
UByte::class.java -> UByteKeyDeserializer
67+
UShort::class.java -> UShortKeyDeserializer
68+
UInt::class.java -> UIntKeyDeserializer
69+
ULong::class.java -> ULongKeyDeserializer
70+
else -> null
71+
}
72+
}

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class KotlinModule @Deprecated(
122122
context.appendAnnotationIntrospector(KotlinNamesAnnotationIntrospector(this, cache, ignoredClassesForImplyingJsonCreator))
123123

124124
context.addDeserializers(KotlinDeserializers())
125+
context.addKeyDeserializers(KotlinKeyDeserializers)
125126
context.addSerializers(KotlinSerializers())
126127
context.addKeySerializers(KotlinKeySerializers())
127128

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinSerializers.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@file:Suppress("EXPERIMENTAL_API_USAGE")
2-
31
package com.fasterxml.jackson.module.kotlin
42

53
import com.fasterxml.jackson.core.JsonGenerator
@@ -57,7 +55,6 @@ object ValueClassUnboxSerializer : StdSerializer<Any>(Any::class.java) {
5755
}
5856
}
5957

60-
@Suppress("EXPERIMENTAL_API_USAGE")
6158
internal class KotlinSerializers : Serializers.Base() {
6259
override fun findSerializer(
6360
config: SerializationConfig?,

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinValueInstantiator.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,15 @@ internal class KotlinInstantiators(
201201
defaultInstantiator: ValueInstantiator
202202
): ValueInstantiator {
203203
return if (beanDescriptor.beanClass.isKotlinClass()) {
204-
if (defaultInstantiator is StdValueInstantiator) {
205-
KotlinValueInstantiator(defaultInstantiator, cache, nullToEmptyCollection, nullToEmptyMap, nullIsSameAsDefault, strictNullChecks)
204+
if (defaultInstantiator::class == StdValueInstantiator::class) {
205+
KotlinValueInstantiator(
206+
defaultInstantiator as StdValueInstantiator,
207+
cache,
208+
nullToEmptyCollection,
209+
nullToEmptyMap,
210+
nullIsSameAsDefault,
211+
strictNullChecks
212+
)
206213
} else {
207214
// TODO: return defaultInstantiator and let default method parameters and nullability go unused? or die with exception:
208215
throw IllegalStateException("KotlinValueInstantiator requires that the default ValueInstantiator is StdValueInstantiator")

src/main/kotlin/com/fasterxml/jackson/module/kotlin/UnsignedNumbers.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
@file:Suppress("EXPERIMENTAL_API_USAGE")
2-
31
package com.fasterxml.jackson.module.kotlin
42

53
import java.math.BigInteger
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.fasterxml.jackson.module.kotlin
2+
3+
import com.fasterxml.jackson.databind.deser.std.StdValueInstantiator
4+
import org.junit.Assert.*
5+
import org.junit.Test
6+
7+
class KotlinInstantiatorsTest {
8+
private val mapper = jacksonObjectMapper()
9+
private val deserConfig = mapper.deserializationConfig
10+
11+
private val kotlinInstantiators = KotlinInstantiators(
12+
ReflectionCache(10),
13+
nullToEmptyCollection = false,
14+
nullToEmptyMap = false,
15+
nullIsSameAsDefault = false,
16+
strictNullChecks = false
17+
)
18+
19+
@Test
20+
fun `Provides default instantiator for Java class`() {
21+
val javaType = mapper.constructType(String::class.java)
22+
val defaultInstantiator = StdValueInstantiator(deserConfig, javaType)
23+
val instantiator = kotlinInstantiators.findValueInstantiator(
24+
deserConfig,
25+
deserConfig.introspect(javaType),
26+
defaultInstantiator
27+
)
28+
29+
assertEquals(defaultInstantiator, instantiator)
30+
}
31+
32+
@Test
33+
fun `Provides KotlinValueInstantiator for Kotlin class`() {
34+
class TestClass
35+
36+
val javaType = mapper.constructType(TestClass::class.java)
37+
val instantiator = kotlinInstantiators.findValueInstantiator(
38+
deserConfig,
39+
deserConfig.introspect(javaType),
40+
StdValueInstantiator(deserConfig, javaType)
41+
)
42+
43+
assertTrue(instantiator is StdValueInstantiator)
44+
assertTrue(instantiator::class == KotlinValueInstantiator::class)
45+
}
46+
47+
@Test
48+
fun `Throws for Kotlin class when default instantiator isn't StdValueInstantiator`() {
49+
class TestClass
50+
class DefaultClass
51+
52+
val subClassInstantiator = object : StdValueInstantiator(
53+
deserConfig,
54+
mapper.constructType(DefaultClass::class.java)
55+
) {}
56+
57+
assertThrows(IllegalStateException::class.java) {
58+
kotlinInstantiators.findValueInstantiator(
59+
deserConfig,
60+
deserConfig.introspect(mapper.constructType(TestClass::class.java)),
61+
subClassInstantiator
62+
)
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)