Skip to content

Commit 991b3d1

Browse files
chore(internal): codegen related update (#271)
1 parent 632d820 commit 991b3d1

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

onebusaway-sdk-kotlin-core/src/main/kotlin/org/onebusaway/core/ObjectMappers.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,43 @@
33
package org.onebusaway.core
44

55
import com.fasterxml.jackson.annotation.JsonInclude
6+
import com.fasterxml.jackson.core.JsonGenerator
67
import com.fasterxml.jackson.databind.DeserializationFeature
78
import com.fasterxml.jackson.databind.SerializationFeature
9+
import com.fasterxml.jackson.databind.SerializerProvider
810
import com.fasterxml.jackson.databind.cfg.CoercionAction.Fail
911
import com.fasterxml.jackson.databind.cfg.CoercionInputShape.Integer
1012
import com.fasterxml.jackson.databind.json.JsonMapper
13+
import com.fasterxml.jackson.databind.module.SimpleModule
1114
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
1215
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
1316
import com.fasterxml.jackson.module.kotlin.jacksonMapperBuilder
17+
import java.io.InputStream
1418

1519
fun jsonMapper(): JsonMapper =
1620
jacksonMapperBuilder()
1721
.addModule(Jdk8Module())
1822
.addModule(JavaTimeModule())
23+
.addModule(SimpleModule().addSerializer(InputStreamJsonSerializer))
1924
.serializationInclusion(JsonInclude.Include.NON_ABSENT)
2025
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
2126
.disable(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)
2227
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
2328
.disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
2429
.withCoercionConfig(String::class.java) { it.setCoercion(Integer, Fail) }
2530
.build()
31+
32+
private object InputStreamJsonSerializer : BaseSerializer<InputStream>(InputStream::class) {
33+
34+
override fun serialize(
35+
value: InputStream?,
36+
gen: JsonGenerator?,
37+
serializers: SerializerProvider?,
38+
) {
39+
if (value == null) {
40+
gen?.writeNull()
41+
} else {
42+
value.use { gen?.writeBinary(it.readBytes()) }
43+
}
44+
}
45+
}

onebusaway-sdk-kotlin-core/src/main/kotlin/org/onebusaway/core/Values.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.node.JsonNodeType.POJO
2727
import com.fasterxml.jackson.databind.node.JsonNodeType.STRING
2828
import com.fasterxml.jackson.databind.ser.std.NullSerializer
2929
import com.fasterxml.jackson.module.kotlin.jacksonTypeRef
30+
import java.io.InputStream
3031
import java.util.Objects
3132
import kotlin.reflect.KClass
3233
import org.onebusaway.errors.OnebusawaySdkInvalidDataException
@@ -491,7 +492,10 @@ private constructor(val value: JsonField<T>, val contentType: String, val filena
491492
return MultipartField(
492493
value,
493494
contentType
494-
?: if (value is KnownValue && value.value is ByteArray)
495+
?: if (
496+
value is KnownValue &&
497+
(value.value is InputStream || value.value is ByteArray)
498+
)
495499
"application/octet-stream"
496500
else "text/plain; charset=utf-8",
497501
filename,

onebusaway-sdk-kotlin-core/src/main/kotlin/org/onebusaway/core/http/HttpRequestBodies.kt

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ package org.onebusaway.core.http
55
import com.fasterxml.jackson.databind.JsonNode
66
import com.fasterxml.jackson.databind.json.JsonMapper
77
import com.fasterxml.jackson.databind.node.JsonNodeType
8+
import java.io.ByteArrayInputStream
9+
import java.io.InputStream
810
import java.io.OutputStream
911
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder
1012
import org.apache.hc.core5.http.ContentType
@@ -36,8 +38,18 @@ internal fun multipartFormData(
3638
MultipartEntityBuilder.create()
3739
.apply {
3840
fields.forEach { (name, field) ->
39-
val node = jsonMapper.valueToTree<JsonNode>(field.value)
40-
serializePart(name, node).forEach { (name, bytes) ->
41+
val knownValue = field.value.asKnown()
42+
val parts =
43+
if (knownValue is InputStream) {
44+
// Read directly from the `InputStream` instead of reading it all
45+
// into memory due to the `jsonMapper` serialization below.
46+
sequenceOf(name to knownValue)
47+
} else {
48+
val node = jsonMapper.valueToTree<JsonNode>(field.value)
49+
serializePart(name, node)
50+
}
51+
52+
parts.forEach { (name, bytes) ->
4153
addBinaryBody(
4254
name,
4355
bytes,
@@ -50,16 +62,19 @@ internal fun multipartFormData(
5062
.build()
5163
}
5264

53-
private fun serializePart(name: String, node: JsonNode): Sequence<Pair<String, ByteArray>> =
65+
private fun serializePart(
66+
name: String,
67+
node: JsonNode,
68+
): Sequence<Pair<String, InputStream>> =
5469
when (node.nodeType) {
5570
JsonNodeType.MISSING,
5671
JsonNodeType.NULL -> emptySequence()
57-
JsonNodeType.BINARY -> sequenceOf(name to node.binaryValue())
58-
JsonNodeType.STRING -> sequenceOf(name to node.textValue().toByteArray())
72+
JsonNodeType.BINARY -> sequenceOf(name to ByteArrayInputStream(node.binaryValue()))
73+
JsonNodeType.STRING -> sequenceOf(name to node.textValue().toInputStream())
5974
JsonNodeType.BOOLEAN ->
60-
sequenceOf(name to node.booleanValue().toString().toByteArray())
75+
sequenceOf(name to node.booleanValue().toString().toInputStream())
6176
JsonNodeType.NUMBER ->
62-
sequenceOf(name to node.numberValue().toString().toByteArray())
77+
sequenceOf(name to node.numberValue().toString().toInputStream())
6378
JsonNodeType.ARRAY ->
6479
node.elements().asSequence().flatMap { element -> serializePart(name, element) }
6580
JsonNodeType.OBJECT ->
@@ -73,6 +88,8 @@ internal fun multipartFormData(
7388
)
7489
}
7590

91+
private fun String.toInputStream(): InputStream = ByteArrayInputStream(toByteArray())
92+
7693
override fun writeTo(outputStream: OutputStream) = entity.writeTo(outputStream)
7794

7895
override fun contentType(): String = entity.contentType

0 commit comments

Comments
 (0)