@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.JsonSerializer
9
9
import com.fasterxml.jackson.databind.MappingIterator
10
10
import com.fasterxml.jackson.databind.ObjectMapper
11
11
import com.fasterxml.jackson.databind.ObjectReader
12
+ import com.fasterxml.jackson.databind.RuntimeJsonMappingException
12
13
import com.fasterxml.jackson.databind.json.JsonMapper
13
14
import com.fasterxml.jackson.databind.module.SimpleModule
14
15
import com.fasterxml.jackson.databind.node.ArrayNode
@@ -52,28 +53,138 @@ public fun ObjectMapper.registerKotlinModule(
52
53
53
54
public inline fun <reified T > jacksonTypeRef (): TypeReference <T > = object : TypeReference <T >() {}
54
55
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
+ */
55
82
public inline fun <reified T > ObjectMapper.readValue (jp : JsonParser ): T = readValue(jp, jacksonTypeRef<T >())
83
+ .checkTypeMismatch()
84
+
85
+ // TODO: After importing 2.19, import the changes in kotlin-module and uncomment the tests.
56
86
public inline fun <reified T > ObjectMapper.readValues (
57
87
jp : JsonParser
58
88
): MappingIterator <T > = readValues(jp, jacksonTypeRef<T >())
59
89
90
+ /* *
91
+ * Shorthand for [ObjectMapper.readValue].
92
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
93
+ * Other cases where the read value is of a different type than [T]
94
+ * due to an incorrect customization to [ObjectMapper].
95
+ */
60
96
public inline fun <reified T > ObjectMapper.readValue (src : File ): T = readValue(src, jacksonTypeRef<T >())
97
+ .checkTypeMismatch()
98
+
99
+ /* *
100
+ * Shorthand for [ObjectMapper.readValue].
101
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
102
+ * Other cases where the read value is of a different type than [T]
103
+ * due to an incorrect customization to [ObjectMapper].
104
+ */
61
105
public inline fun <reified T > ObjectMapper.readValue (src : URL ): T = readValue(src, jacksonTypeRef<T >())
106
+ .checkTypeMismatch()
107
+
108
+ /* *
109
+ * Shorthand for [ObjectMapper.readValue].
110
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
111
+ * Other cases where the read value is of a different type than [T]
112
+ * due to an incorrect customization to [ObjectMapper].
113
+ */
62
114
public inline fun <reified T > ObjectMapper.readValue (content : String ): T = readValue(content, jacksonTypeRef<T >())
115
+ .checkTypeMismatch()
116
+
117
+ /* *
118
+ * Shorthand for [ObjectMapper.readValue].
119
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
120
+ * Other cases where the read value is of a different type than [T]
121
+ * due to an incorrect customization to [ObjectMapper].
122
+ */
63
123
public inline fun <reified T > ObjectMapper.readValue (src : Reader ): T = readValue(src, jacksonTypeRef<T >())
124
+ .checkTypeMismatch()
125
+
126
+ /* *
127
+ * Shorthand for [ObjectMapper.readValue].
128
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
129
+ * Other cases where the read value is of a different type than [T]
130
+ * due to an incorrect customization to [ObjectMapper].
131
+ */
64
132
public inline fun <reified T > ObjectMapper.readValue (src : InputStream ): T = readValue(src, jacksonTypeRef<T >())
133
+ .checkTypeMismatch()
134
+
135
+ /* *
136
+ * Shorthand for [ObjectMapper.readValue].
137
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
138
+ * Other cases where the read value is of a different type than [T]
139
+ * due to an incorrect customization to [ObjectMapper].
140
+ */
65
141
public inline fun <reified T > ObjectMapper.readValue (src : ByteArray ): T = readValue(src, jacksonTypeRef<T >())
142
+ .checkTypeMismatch()
143
+
144
+ /* *
145
+ * Shorthand for [ObjectMapper.readValue].
146
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
147
+ * Other cases where the read value is of a different type than [T]
148
+ * due to an incorrect customization to [ObjectMapper].
149
+ */
150
+ public inline fun <reified T > ObjectMapper.treeToValue (
151
+ n : TreeNode
152
+ ): T = readValue(this .treeAsTokens(n), jacksonTypeRef<T >()).checkTypeMismatch()
66
153
67
- public inline fun <reified T > ObjectMapper.treeToValue (n : TreeNode ): T = readValue(treeAsTokens(n), jacksonTypeRef<T >())
154
+ /* *
155
+ * Shorthand for [ObjectMapper.convertValue].
156
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
157
+ * Other cases where the read value is of a different type than [T]
158
+ * due to an incorrect customization to [ObjectMapper].
159
+ */
68
160
public inline fun <reified T > ObjectMapper.convertValue (from : Any? ): T = convertValue(from, jacksonTypeRef<T >())
161
+ .checkTypeMismatch()
69
162
163
+ /* *
164
+ * Shorthand for [ObjectReader.readValue].
165
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
166
+ * Other cases where the read value is of a different type than [T]
167
+ * due to an incorrect customization to [ObjectReader].
168
+ */
70
169
public 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 >())
170
+ .checkTypeMismatch()
171
+
172
+ /* *
173
+ * Shorthand for [ObjectReader.readValues].
174
+ * @throws RuntimeJsonMappingException Especially if [T] is non-null and the value read is null.
175
+ * Other cases where the read value is of a different type than [T]
176
+ * due to an incorrect customization to [ObjectReader].
177
+ */
178
+ public inline fun <reified T > ObjectReader.readValuesTyped (jp : JsonParser ): Iterator <T > {
179
+ val values = readValues(jp, jacksonTypeRef<T >())
180
+
181
+ return object : Iterator <T > by values {
182
+ override fun next (): T = values.next().checkTypeMismatch<T >()
183
+ }
184
+ }
74
185
public inline fun <reified T > ObjectReader.treeToValue (
75
186
n : TreeNode
76
- ): T ? = readValue(treeAsTokens(n), jacksonTypeRef<T >())
187
+ ): T ? = readValue(this . treeAsTokens(n), jacksonTypeRef<T >())
77
188
78
189
public inline fun <reified T , reified U > ObjectMapper.addMixIn (): ObjectMapper = addMixIn(T ::class .java, U ::class .java)
79
190
public inline fun <reified T , reified U > JsonMapper.Builder.addMixIn (): JsonMapper .Builder = addMixIn(
0 commit comments