Skip to content

Commit 32ff52b

Browse files
authored
New iterable serializer (#468)
1 parent a4c8852 commit 32ff52b

File tree

2 files changed

+106
-7
lines changed

2 files changed

+106
-7
lines changed

src/main/scala/com/fasterxml/jackson/module/scala/ser/IterableSerializerModule.scala

+5-7
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,22 @@ import java.{lang => jl}
77
import com.fasterxml.jackson.core.JsonGenerator
88
import com.fasterxml.jackson.databind.`type`.CollectionLikeType
99
import com.fasterxml.jackson.databind.jsontype.TypeSerializer
10-
import com.fasterxml.jackson.databind.ser.std.{AsArraySerializerBase, CollectionSerializer}
10+
import com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase
1111
import com.fasterxml.jackson.databind.ser.{ContainerSerializer, Serializers}
1212
import com.fasterxml.jackson.databind._
1313
import com.fasterxml.jackson.module.scala.modifiers.IterableTypeModifierModule
1414

15-
import scala.collection.JavaConverters._
16-
1715
private trait IterableSerializer
1816
extends AsArraySerializerBase[collection.Iterable[Any]]
1917
{
20-
def collectionSerializer: CollectionSerializer
18+
def collectionSerializer: ScalaIterableSerializer
2119

2220
override def hasSingleElement(value: collection.Iterable[Any]): Boolean = {
2321
value.size == 1
2422
}
2523

2624
override def serializeContents(value: collection.Iterable[Any], gen: JsonGenerator, provider: SerializerProvider): Unit = {
27-
collectionSerializer.serializeContents(value.asJavaCollection, gen, provider)
25+
collectionSerializer.serializeContents(value, gen, provider)
2826
}
2927

3028
override def withResolved(property: BeanProperty,
@@ -45,7 +43,7 @@ private class ResolvedIterableSerializer( src: IterableSerializer,
4543
with IterableSerializer
4644
{
4745
val collectionSerializer =
48-
new CollectionSerializer(src.collectionSerializer, property, vts, elementSerializer, unwrapSingle)
46+
new ScalaIterableSerializer(src.collectionSerializer, property, vts, elementSerializer)
4947

5048
override def _withValueTypeSerializer(newVts: TypeSerializer): ContainerSerializer[_] =
5149
new ResolvedIterableSerializer(this, property, newVts, elementSerializer, unwrapSingle)
@@ -61,7 +59,7 @@ private class UnresolvedIterableSerializer( cls: Class[_],
6159
with IterableSerializer
6260
{
6361
val collectionSerializer =
64-
new CollectionSerializer(et, staticTyping, vts, elementSerializer)
62+
new ScalaIterableSerializer(et, staticTyping, vts, elementSerializer)
6563

6664
override def _withValueTypeSerializer(newVts: TypeSerializer): ContainerSerializer[_] =
6765
new UnresolvedIterableSerializer(cls, et, staticTyping, newVts, elementSerializer)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.fasterxml.jackson.module.scala.ser
2+
3+
import java.{lang => jl}
4+
5+
import com.fasterxml.jackson.core.JsonGenerator
6+
import com.fasterxml.jackson.databind.jsontype.TypeSerializer
7+
import com.fasterxml.jackson.databind.ser.ContainerSerializer
8+
import com.fasterxml.jackson.databind.ser.std.AsArraySerializerBase
9+
import com.fasterxml.jackson.databind.{BeanProperty, JavaType, JsonSerializer, SerializationFeature, SerializerProvider}
10+
11+
case class ScalaIterableSerializer(elemType: JavaType, staticTyping: Boolean, vts: TypeSerializer,
12+
property: BeanProperty, valueSerializer: JsonSerializer[Object])
13+
extends AsArraySerializerBase[collection.Iterable[Any]](collection.Iterable.getClass, elemType, staticTyping, vts, property, valueSerializer) {
14+
15+
def this(elemType: JavaType, staticTyping: Boolean, vts: TypeSerializer, valueSerializer: JsonSerializer[Object]) {
16+
this(elemType, staticTyping, vts, None.orNull, valueSerializer.asInstanceOf[JsonSerializer[Object]])
17+
}
18+
19+
def this(src: ScalaIterableSerializer, property: BeanProperty, vts: TypeSerializer, valueSerializer: JsonSerializer[_]) {
20+
this(src.elemType, src.staticTyping, vts, property, valueSerializer.asInstanceOf[JsonSerializer[Object]])
21+
}
22+
23+
override def isEmpty(prov: SerializerProvider, value: Iterable[Any]): Boolean = value.isEmpty
24+
25+
override def hasSingleElement(value: Iterable[Any]): Boolean = value.size == 1
26+
27+
override def serialize(value: Iterable[Any], g: JsonGenerator, provider: SerializerProvider): Unit = {
28+
val len: Int = value.size
29+
if (len == 1 &&
30+
(_unwrapSingle == null && provider.isEnabled(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED)) || (_unwrapSingle)) {
31+
serializeContents(value, g, provider)
32+
} else {
33+
g.writeStartArray(value, len)
34+
serializeContents(value, g, provider)
35+
g.writeEndArray()
36+
}
37+
}
38+
39+
override def serializeContents(value: Iterable[Any], g: JsonGenerator, provider: SerializerProvider): Unit = {
40+
g.setCurrentValue(value)
41+
if (_elementSerializer != null) {
42+
serializeContentsUsing(value, g, provider, _elementSerializer)
43+
} else {
44+
val it = value.iterator
45+
if (it.hasNext) {
46+
val typeSer = _valueTypeSerializer
47+
var serializers = _dynamicSerializers
48+
var i = 0
49+
try do {
50+
val elem = it.next
51+
if (elem == null) provider.defaultSerializeNull(g)
52+
else {
53+
val cc = elem.getClass
54+
var serializer = serializers.serializerFor(cc)
55+
if (serializer == null) {
56+
if (_elementType.hasGenericTypes) serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider)
57+
else serializer = _findAndAddDynamic(serializers, cc, provider)
58+
serializers = _dynamicSerializers
59+
}
60+
if (typeSer == null) serializer.serialize(elem.asInstanceOf[Object], g, provider)
61+
else serializer.serializeWithType(elem.asInstanceOf[Object], g, provider, typeSer)
62+
}
63+
i += 1
64+
} while (it.hasNext)
65+
catch {
66+
case e: Exception =>
67+
wrapAndThrow(provider, e, value, i)
68+
}
69+
}
70+
}
71+
}
72+
73+
override def withResolved(property: BeanProperty, vts: TypeSerializer, elementSerializer: JsonSerializer[_],
74+
unwrapSingle: jl.Boolean): AsArraySerializerBase[Iterable[Any]] = {
75+
new ScalaIterableSerializer(this, property, vts, elementSerializer)
76+
}
77+
78+
override def _withValueTypeSerializer(vts: TypeSerializer): ContainerSerializer[_] = {
79+
new ScalaIterableSerializer(this, _property, vts, _elementSerializer)
80+
}
81+
82+
private def serializeContentsUsing(value: Iterable[Any], g: JsonGenerator, provider: SerializerProvider, ser: JsonSerializer[AnyRef]): Unit = {
83+
val it = value.iterator
84+
if (it.hasNext) {
85+
val typeSer = _valueTypeSerializer
86+
var i = 0
87+
do {
88+
val elem = it.next
89+
try {
90+
if (elem == null) provider.defaultSerializeNull(g)
91+
else if (typeSer == null) ser.serialize(elem.asInstanceOf[Object], g, provider)
92+
else ser.serializeWithType(elem.asInstanceOf[Object], g, provider, typeSer)
93+
i += 1
94+
} catch {
95+
case e: Exception =>
96+
wrapAndThrow(provider, e, value, i)
97+
}
98+
} while (it.hasNext)
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)