@@ -7,15 +7,19 @@ import com.fasterxml.jackson.core.{JsonParser, TreeNode}
7
7
import com .fasterxml .jackson .databind .jsonFormatVisitors .JsonFormatVisitorWrapper
8
8
import com .fasterxml .jackson .databind .jsonschema .JsonSchema
9
9
import com .fasterxml .jackson .databind ._
10
+ import com .fasterxml .jackson .databind .`type` .TypeFactory
10
11
import com .fasterxml .jackson .databind .json .JsonMapper
12
+ import com .fasterxml .jackson .databind .jsonFormatVisitors .JsonFormatVisitorWrapper
13
+
14
+ import scala .reflect .{ClassTag , classTag }
11
15
12
16
object ScalaObjectMapper {
13
17
def :: (o : JsonMapper ) = new Mixin (o)
14
18
final class Mixin private [ScalaObjectMapper ](mapper : JsonMapper )
15
19
extends JsonMapper (mapper.rebuild().build()) with ScalaObjectMapper
16
20
}
17
21
18
- @ deprecated(" ScalaObjectMapper is deprecated because Manifests are not supported in Scala3" , " 2.12.1" )
22
+ // @deprecated("ScalaObjectMapper is deprecated because Manifests are not supported in Scala3", "2.12.1")
19
23
trait ScalaObjectMapper {
20
24
self : ObjectMapper =>
21
25
@@ -64,6 +68,8 @@ trait ScalaObjectMapper {
64
68
* type (typically <code>java.lang.Class</code>), but without explicit
65
69
* context.
66
70
*/
71
+ def constructType [T ](implicit m : JavaTypeable [T ]): JavaType = {
72
+ m.asJavaType(getTypeFactory)
67
73
def constructType [T ](implicit m : Manifest [T ]): JavaType = {
68
74
val clazz = m.runtimeClass
69
75
if (isArray(clazz)) {
@@ -111,7 +117,7 @@ trait ScalaObjectMapper {
111
117
* and specifically needs to be used if the root type is a
112
118
* parameterized (generic) container type.
113
119
*/
114
- def readValue [T : Manifest ](jp : JsonParser ): T = {
120
+ def readValue [T : JavaTypeable ](jp : JsonParser ): T = {
115
121
readValue(jp, constructType[T ])
116
122
}
117
123
@@ -127,7 +133,7 @@ trait ScalaObjectMapper {
127
133
* <p>
128
134
* Note that [[com.fasterxml.jackson.databind.ObjectReader ]] has more complete set of variants.
129
135
*/
130
- def readValues [T : Manifest ](jp : JsonParser ): MappingIterator [T ] = {
136
+ def readValues [T : JavaTypeable ](jp : JsonParser ): MappingIterator [T ] = {
131
137
readValues(jp, constructType[T ])
132
138
}
133
139
@@ -146,8 +152,8 @@ trait ScalaObjectMapper {
146
152
* objectMapper.convertValue(n, valueClass);
147
153
* </pre>
148
154
*/
149
- def treeToValue [T : Manifest ](n : TreeNode ): T = {
150
- treeToValue(n, manifest [T ].runtimeClass).asInstanceOf [T ]
155
+ def treeToValue [T : ClassTag ](n : TreeNode ): T = {
156
+ treeToValue(n, classTag [T ].runtimeClass).asInstanceOf [T ]
151
157
}
152
158
153
159
/*
@@ -194,63 +200,63 @@ trait ScalaObjectMapper {
194
200
* convenience methods
195
201
**********************************************************
196
202
*/
197
- def readValue [T : Manifest ](src : File ): T = {
203
+ def readValue [T : JavaTypeable ](src : File ): T = {
198
204
readValue(src, constructType[T ])
199
205
}
200
206
201
- def readValue [T : Manifest ](src : URL ): T = {
207
+ def readValue [T : JavaTypeable ](src : URL ): T = {
202
208
readValue(src, constructType[T ])
203
209
}
204
210
205
- def readValue [T : Manifest ](content : String ): T = {
211
+ def readValue [T : JavaTypeable ](content : String ): T = {
206
212
readValue(content, constructType[T ])
207
213
}
208
214
209
- def readValue [T : Manifest ](src : Reader ): T = {
215
+ def readValue [T : JavaTypeable ](src : Reader ): T = {
210
216
readValue(src, constructType[T ])
211
217
}
212
218
213
- def readValue [T : Manifest ](src : InputStream ): T = {
219
+ def readValue [T : JavaTypeable ](src : InputStream ): T = {
214
220
readValue(src, constructType[T ])
215
221
}
216
222
217
- def readValue [T : Manifest ](src : Array [Byte ]): T = {
223
+ def readValue [T : JavaTypeable ](src : Array [Byte ]): T = {
218
224
readValue(src, constructType[T ])
219
225
}
220
226
221
- def readValue [T : Manifest ](src : Array [Byte ], offset : Int , len : Int ): T = {
227
+ def readValue [T : JavaTypeable ](src : Array [Byte ], offset : Int , len : Int ): T = {
222
228
readValue(src, offset, len, constructType[T ])
223
229
}
224
230
225
- def updateValue [T : Manifest ](valueToUpdate : T , src : File ): T = {
231
+ def updateValue [T : JavaTypeable ](valueToUpdate : T , src : File ): T = {
226
232
objectReaderFor(valueToUpdate).readValue(src)
227
233
}
228
234
229
- def updateValue [T : Manifest ](valueToUpdate : T , src : URL ): T = {
235
+ def updateValue [T : JavaTypeable ](valueToUpdate : T , src : URL ): T = {
230
236
objectReaderFor(valueToUpdate).readValue(src)
231
237
}
232
238
233
- def updateValue [T : Manifest ](valueToUpdate : T , content : String ): T = {
239
+ def updateValue [T : JavaTypeable ](valueToUpdate : T , content : String ): T = {
234
240
objectReaderFor(valueToUpdate).readValue(content)
235
241
}
236
242
237
- def updateValue [T : Manifest ](valueToUpdate : T , src : Reader ): T = {
243
+ def updateValue [T : JavaTypeable ](valueToUpdate : T , src : Reader ): T = {
238
244
objectReaderFor(valueToUpdate).readValue(src)
239
245
}
240
246
241
- def updateValue [T : Manifest ](valueToUpdate : T , src : InputStream ): T = {
247
+ def updateValue [T : JavaTypeable ](valueToUpdate : T , src : InputStream ): T = {
242
248
objectReaderFor(valueToUpdate).readValue(src)
243
249
}
244
250
245
- def updateValue [T : Manifest ](valueToUpdate : T , src : Array [Byte ]): T = {
251
+ def updateValue [T : JavaTypeable ](valueToUpdate : T , src : Array [Byte ]): T = {
246
252
objectReaderFor(valueToUpdate).readValue(src)
247
253
}
248
254
249
- def updateValue [T : Manifest ](valueToUpdate : T , src : Array [Byte ], offset : Int , len : Int ): T = {
255
+ def updateValue [T : JavaTypeable ](valueToUpdate : T , src : Array [Byte ], offset : Int , len : Int ): T = {
250
256
objectReaderFor(valueToUpdate).readValue(src, offset, len)
251
257
}
252
258
253
- private def objectReaderFor [T : Manifest ](valueToUpdate : T ): ObjectReader = {
259
+ private def objectReaderFor [T : JavaTypeable ](valueToUpdate : T ): ObjectReader = {
254
260
readerForUpdating(valueToUpdate).forType(constructType[T ])
255
261
}
256
262
@@ -265,8 +271,8 @@ trait ScalaObjectMapper {
265
271
* Factory method for constructing [[com.fasterxml.jackson.databind.ObjectWriter ]] that will
266
272
* serialize objects using specified JSON View (filter).
267
273
*/
268
- def writerWithView [T : Manifest ]: ObjectWriter = {
269
- writerWithView(manifest [T ].runtimeClass)
274
+ def writerWithView [T : ClassTag ]: ObjectWriter = {
275
+ writerWithView(classTag [T ].runtimeClass)
270
276
}
271
277
272
278
/**
@@ -288,7 +294,7 @@ trait ScalaObjectMapper {
288
294
*
289
295
* @since 2.5
290
296
*/
291
- def writerFor [T : Manifest ]: ObjectWriter = {
297
+ def writerFor [T : JavaTypeable ]: ObjectWriter = {
292
298
writerFor(constructType[T ])
293
299
}
294
300
@@ -312,16 +318,16 @@ trait ScalaObjectMapper {
312
318
* Factory method for constructing [[com.fasterxml.jackson.databind.ObjectReader ]] that will
313
319
* read or update instances of specified type
314
320
*/
315
- def readerFor [T : Manifest ]: ObjectReader = {
321
+ def readerFor [T : JavaTypeable ]: ObjectReader = {
316
322
readerFor(constructType[T ])
317
323
}
318
324
319
325
/**
320
326
* Factory method for constructing [[com.fasterxml.jackson.databind.ObjectReader ]] that will
321
327
* deserialize objects using specified JSON View (filter).
322
328
*/
323
- def readerWithView [T : Manifest ]: ObjectReader = {
324
- readerWithView(manifest [T ].runtimeClass)
329
+ def readerWithView [T : ClassTag ]: ObjectReader = {
330
+ readerWithView(classTag [T ].runtimeClass)
325
331
}
326
332
327
333
/*
@@ -342,7 +348,7 @@ trait ScalaObjectMapper {
342
348
* if so, root cause will contain underlying checked exception data binding
343
349
* functionality threw
344
350
*/
345
- def convertValue [T : Manifest ](fromValue : Any ): T = {
351
+ def convertValue [T : JavaTypeable ](fromValue : Any ): T = {
346
352
convertValue(fromValue, constructType[T ])
347
353
}
348
354
@@ -375,26 +381,109 @@ trait ScalaObjectMapper {
375
381
*
376
382
* @since 2.1
377
383
*/
378
- def acceptJsonFormatVisitor [T : Manifest ](visitor : JsonFormatVisitorWrapper ): Unit = {
379
- acceptJsonFormatVisitor(manifest [T ].runtimeClass, visitor)
384
+ def acceptJsonFormatVisitor [T : ClassTag ](visitor : JsonFormatVisitorWrapper ): Unit = {
385
+ acceptJsonFormatVisitor(classTag [T ].runtimeClass, visitor)
380
386
}
381
387
382
- private def isArray (c : Class [_]): Boolean = {
383
- c.isArray
388
+ }
389
+
390
+ trait JavaTypeable [T ] {
391
+ def asJavaType (typeFactory : TypeFactory ): JavaType
392
+ }
393
+
394
+ object JavaTypeable {
395
+
396
+ implicit val anyJavaTypeable : JavaTypeable [Any ] = {
397
+ new JavaTypeable [Any ] {
398
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
399
+ val typeArgs : Array [JavaType ] = Array ()
400
+ typeFactory.constructParametricType(classOf [Object ], typeArgs : _* )
401
+ }
402
+ }
384
403
}
385
404
386
- private val MAP = classOf [collection.Map [_,_]]
387
- private def isMapLike (c : Class [_]): Boolean = {
388
- MAP .isAssignableFrom(c)
405
+ implicit def optionJavaTypeable [T : JavaTypeable ]: JavaTypeable [Option [T ]] = {
406
+ new JavaTypeable [Option [T ]] {
407
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
408
+ val typeArg0 = implicitly[JavaTypeable [T ]].asJavaType(typeFactory)
409
+ typeFactory.constructReferenceType(classOf [Option [_]], typeArg0)
410
+ }
411
+ }
389
412
}
390
413
391
- private val OPTION = classOf [Option [_]]
392
- private def isReference (c : Class [_]): Boolean = {
393
- OPTION .isAssignableFrom(c)
414
+ implicit def arrayJavaTypeable [T : JavaTypeable ]: JavaTypeable [Array [T ]] = {
415
+ new JavaTypeable [Array [T ]] {
416
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
417
+ val typeArg0 = implicitly[JavaTypeable [T ]].asJavaType(typeFactory)
418
+ typeFactory.constructArrayType(typeArg0)
419
+ }
420
+ }
394
421
}
395
422
396
- private val ITERABLE = classOf [collection.Iterable [_]]
397
- private def isCollectionLike (c : Class [_]): Boolean = {
398
- ITERABLE .isAssignableFrom(c)
423
+ implicit def mapJavaTypeable [M [_,_] <: Map [_,_], K : JavaTypeable , V : JavaTypeable ](implicit ct : ClassTag [M [K ,V ]]): JavaTypeable [M [K , V ]] = {
424
+ new JavaTypeable [M [K , V ]] {
425
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
426
+ val typeArg0 = implicitly[JavaTypeable [K ]].asJavaType(typeFactory)
427
+ val typeArg1 = implicitly[JavaTypeable [V ]].asJavaType(typeFactory)
428
+ typeFactory.constructMapLikeType(ct.runtimeClass, typeArg0, typeArg1)
429
+ }
430
+ }
431
+ }
432
+
433
+ implicit def collectionJavaTypeable [I [_] <: Iterable [_], T : JavaTypeable ](implicit ct : ClassTag [I [T ]]): JavaTypeable [I [T ]] = {
434
+ new JavaTypeable [I [T ]] {
435
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
436
+ val typeArg0 = implicitly[JavaTypeable [T ]].asJavaType(typeFactory)
437
+ typeFactory.constructCollectionLikeType(ct.runtimeClass, typeArg0)
438
+ }
439
+ }
399
440
}
441
+
442
+ // TODO generate genX for X up to a large enough number, 10? 22?
443
+
444
+ implicit def gen3JavaTypeable [T [_, _, _], A : JavaTypeable , B : JavaTypeable , C : JavaTypeable ](implicit ct : ClassTag [T [A , B , C ]]): JavaTypeable [T [A , B , C ]] = {
445
+ new JavaTypeable [T [A , B , C ]] {
446
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
447
+ val typeArgs : Array [JavaType ] = Array (
448
+ implicitly[JavaTypeable [A ]].asJavaType(typeFactory),
449
+ implicitly[JavaTypeable [B ]].asJavaType(typeFactory),
450
+ implicitly[JavaTypeable [C ]].asJavaType(typeFactory)
451
+ )
452
+ typeFactory.constructParametricType(ct.runtimeClass, typeArgs : _* )
453
+ }
454
+ }
455
+ }
456
+
457
+ implicit def gen2JavaTypeable [T [_, _], A : JavaTypeable , B : JavaTypeable ](implicit ct : ClassTag [T [A , B ]]): JavaTypeable [T [A , B ]] = {
458
+ new JavaTypeable [T [A , B ]] {
459
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
460
+ val typeArgs : Array [JavaType ] = Array (
461
+ implicitly[JavaTypeable [A ]].asJavaType(typeFactory),
462
+ implicitly[JavaTypeable [B ]].asJavaType(typeFactory)
463
+ )
464
+ typeFactory.constructParametricType(ct.runtimeClass, typeArgs : _* )
465
+ }
466
+ }
467
+ }
468
+
469
+ implicit def gen1JavaTypeable [T [_], A : JavaTypeable ](implicit ct : ClassTag [T [A ]]): JavaTypeable [T [A ]] = {
470
+ new JavaTypeable [T [A ]] {
471
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
472
+ val typeArgs : Array [JavaType ] = Array (
473
+ implicitly[JavaTypeable [A ]].asJavaType(typeFactory)
474
+ )
475
+ typeFactory.constructParametricType(ct.runtimeClass, typeArgs : _* )
476
+ }
477
+ }
478
+ }
479
+
480
+ implicit def gen0JavaTypeable [T ](implicit ct : ClassTag [T ]): JavaTypeable [T ] = {
481
+ new JavaTypeable [T ] {
482
+ override def asJavaType (typeFactory : TypeFactory ): JavaType = {
483
+ val typeArgs : Array [JavaType ] = Array ()
484
+ typeFactory.constructParametricType(ct.runtimeClass, typeArgs : _* )
485
+ }
486
+ }
487
+ }
488
+
400
489
}
0 commit comments