@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.JsonSerializer
99import com.fasterxml.jackson.databind.MappingIterator
1010import com.fasterxml.jackson.databind.ObjectMapper
1111import com.fasterxml.jackson.databind.ObjectReader
12+ import com.fasterxml.jackson.databind.RuntimeJsonMappingException
1213import com.fasterxml.jackson.databind.json.JsonMapper
1314import com.fasterxml.jackson.databind.module.SimpleModule
1415import com.fasterxml.jackson.databind.node.ArrayNode
@@ -52,28 +53,133 @@ public fun ObjectMapper.registerKotlinModule(
5253
5354public inline fun <reified T > jacksonTypeRef (): TypeReference <T > = object : TypeReference <T >() {}
5455
56+ /* *
57+ * It is public due to Kotlin restrictions, but should not be used externally.
58+ */
59+ public inline fun <reified T > Any?.checkTypeMismatch (): T {
60+ // Basically, this check assumes that T is non-null and the value is null.
61+ // Since this can be caused by both input or ObjectMapper implementation errors,
62+ // a more abstract RuntimeJsonMappingException is thrown.
63+ if (this !is T ) {
64+ val nullability = if (null is T ) " ?" else " (non-null)"
65+
66+ // Since the databind implementation of MappingIterator throws RuntimeJsonMappingException,
67+ // JsonMappingException was not used to unify the behavior.
68+ throw RuntimeJsonMappingException (
69+ " Deserialized value did not match the specified type; " +
70+ " specified ${T ::class .qualifiedName}$nullability but was ${this ?.let { it::class .qualifiedName }} "
71+ )
72+ }
73+ return this
74+ }
75+
76+ /* *
77+ * Shorthand for [ObjectMapper.readValue].
78+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
79+ * Other cases where the read value is of a different type than [T]
80+ * due to an incorrect customization to [ObjectMapper].
81+ */
5582public inline fun <reified T > ObjectMapper.readValue (jp : JsonParser ): T = readValue(jp, jacksonTypeRef<T >())
56- public inline fun <reified T > ObjectMapper.readValues (
57- jp : JsonParser
58- ): MappingIterator <T > = readValues(jp, jacksonTypeRef<T >())
83+ .checkTypeMismatch()
84+
85+ // TODO: After importing 2.19, import the changes in kotlin-module and uncomment the tests.
86+ public inline fun <reified T > ObjectMapper.readValues (jp : JsonParser ): MappingIterator <T > = readValues(jp, jacksonTypeRef<T >())
5987
88+ /* *
89+ * Shorthand for [ObjectMapper.readValue].
90+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
91+ * Other cases where the read value is of a different type than [T]
92+ * due to an incorrect customization to [ObjectMapper].
93+ */
6094public inline fun <reified T > ObjectMapper.readValue (src : File ): T = readValue(src, jacksonTypeRef<T >())
95+ .checkTypeMismatch()
96+
97+ /* *
98+ * Shorthand for [ObjectMapper.readValue].
99+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
100+ * Other cases where the read value is of a different type than [T]
101+ * due to an incorrect customization to [ObjectMapper].
102+ */
61103public inline fun <reified T > ObjectMapper.readValue (src : URL ): T = readValue(src, jacksonTypeRef<T >())
104+ .checkTypeMismatch()
105+
106+ /* *
107+ * Shorthand for [ObjectMapper.readValue].
108+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
109+ * Other cases where the read value is of a different type than [T]
110+ * due to an incorrect customization to [ObjectMapper].
111+ */
62112public inline fun <reified T > ObjectMapper.readValue (content : String ): T = readValue(content, jacksonTypeRef<T >())
113+ .checkTypeMismatch()
114+
115+ /* *
116+ * Shorthand for [ObjectMapper.readValue].
117+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
118+ * Other cases where the read value is of a different type than [T]
119+ * due to an incorrect customization to [ObjectMapper].
120+ */
63121public inline fun <reified T > ObjectMapper.readValue (src : Reader ): T = readValue(src, jacksonTypeRef<T >())
122+ .checkTypeMismatch()
123+
124+ /* *
125+ * Shorthand for [ObjectMapper.readValue].
126+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
127+ * Other cases where the read value is of a different type than [T]
128+ * due to an incorrect customization to [ObjectMapper].
129+ */
64130public inline fun <reified T > ObjectMapper.readValue (src : InputStream ): T = readValue(src, jacksonTypeRef<T >())
131+ .checkTypeMismatch()
132+
133+ /* *
134+ * Shorthand for [ObjectMapper.readValue].
135+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
136+ * Other cases where the read value is of a different type than [T]
137+ * due to an incorrect customization to [ObjectMapper].
138+ */
65139public inline fun <reified T > ObjectMapper.readValue (src : ByteArray ): T = readValue(src, jacksonTypeRef<T >())
140+ .checkTypeMismatch()
141+
142+ /* *
143+ * Shorthand for [ObjectMapper.readValue].
144+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
145+ * Other cases where the read value is of a different type than [T]
146+ * due to an incorrect customization to [ObjectMapper].
147+ */
148+ public inline fun <reified T > ObjectMapper.treeToValue (n : TreeNode ): T = readValue(this .treeAsTokens(n), jacksonTypeRef<T >())
149+ .checkTypeMismatch()
66150
67- public inline fun <reified T > ObjectMapper.treeToValue (n : TreeNode ): T = readValue(treeAsTokens(n), jacksonTypeRef<T >())
151+ /* *
152+ * Shorthand for [ObjectMapper.convertValue].
153+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
154+ * Other cases where the read value is of a different type than [T]
155+ * due to an incorrect customization to [ObjectMapper].
156+ */
68157public inline fun <reified T > ObjectMapper.convertValue (from : Any? ): T = convertValue(from, jacksonTypeRef<T >())
158+ .checkTypeMismatch()
69159
160+ /* *
161+ * Shorthand for [ObjectReader.readValue].
162+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
163+ * Other cases where the read value is of a different type than [T]
164+ * due to an incorrect customization to [ObjectReader].
165+ */
70166public inline fun <reified T > ObjectReader.readValueTyped (jp : JsonParser ): T = readValue(jp, jacksonTypeRef<T >())
71- public inline fun <reified T > ObjectReader.readValuesTyped (
72- jp : JsonParser
73- ): Iterator <T > = readValues(jp, jacksonTypeRef<T >())
74- public inline fun <reified T > ObjectReader.treeToValue (
75- n : TreeNode
76- ): T ? = readValue(treeAsTokens(n), jacksonTypeRef<T >())
167+ .checkTypeMismatch()
168+
169+ /* *
170+ * Shorthand for [ObjectReader.readValues].
171+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
172+ * Other cases where the read value is of a different type than [T]
173+ * due to an incorrect customization to [ObjectReader].
174+ */
175+ public inline fun <reified T > ObjectReader.readValuesTyped (jp : JsonParser ): Iterator <T > {
176+ val values = readValues(jp, jacksonTypeRef<T >())
177+
178+ return object : Iterator <T > by values {
179+ override fun next (): T = values.next().checkTypeMismatch<T >()
180+ }
181+ }
182+ public inline fun <reified T > ObjectReader.treeToValue (n : TreeNode ): T ? = readValue(this .treeAsTokens(n), jacksonTypeRef<T >())
77183
78184public inline fun <reified T , reified U > ObjectMapper.addMixIn (): ObjectMapper = addMixIn(T ::class .java, U ::class .java)
79185public inline fun <reified T , reified U > JsonMapper.Builder.addMixIn (): JsonMapper .Builder = addMixIn(
0 commit comments