diff --git a/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonDecoder.kt b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonDecoder.kt index 68ecbbabc1..99e5d2acb1 100644 --- a/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonDecoder.kt +++ b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonDecoder.kt @@ -37,10 +37,11 @@ import org.bson.BsonType import org.bson.BsonValue import org.bson.codecs.BsonValueCodec import org.bson.codecs.DecoderContext -import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonArrayDecoder -import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonDocumentDecoder -import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonMapDecoder -import org.bson.codecs.kotlinx.BsonDecoder.Companion.createBsonPolymorphicDecoder +import org.bson.codecs.kotlinx.utils.BsonCodecUtils.createBsonArrayDecoder +import org.bson.codecs.kotlinx.utils.BsonCodecUtils.createBsonDecoder +import org.bson.codecs.kotlinx.utils.BsonCodecUtils.createBsonDocumentDecoder +import org.bson.codecs.kotlinx.utils.BsonCodecUtils.createBsonMapDecoder +import org.bson.codecs.kotlinx.utils.BsonCodecUtils.createBsonPolymorphicDecoder import org.bson.internal.NumberCodecHelper import org.bson.internal.StringCodecHelper import org.bson.types.ObjectId @@ -51,75 +52,12 @@ import org.bson.types.ObjectId * For custom serialization handlers */ @ExperimentalSerializationApi -internal sealed interface BsonDecoder : Decoder, CompositeDecoder { - - /** Factory helper for creating concrete BsonDecoder implementations */ - companion object { - - @Suppress("SwallowedException") - private val hasJsonDecoder: Boolean by lazy { - try { - Class.forName("kotlinx.serialization.json.JsonDecoder") - true - } catch (e: ClassNotFoundException) { - false - } - } - - fun createBsonDecoder( - reader: AbstractBsonReader, - serializersModule: SerializersModule, - configuration: BsonConfiguration - ): BsonDecoder { - return if (hasJsonDecoder) JsonBsonDecoderImpl(reader, serializersModule, configuration) - else BsonDecoderImpl(reader, serializersModule, configuration) - } - - fun createBsonArrayDecoder( - descriptor: SerialDescriptor, - reader: AbstractBsonReader, - serializersModule: SerializersModule, - configuration: BsonConfiguration - ): BsonArrayDecoder { - return if (hasJsonDecoder) JsonBsonArrayDecoder(descriptor, reader, serializersModule, configuration) - else BsonArrayDecoder(descriptor, reader, serializersModule, configuration) - } - - fun createBsonDocumentDecoder( - descriptor: SerialDescriptor, - reader: AbstractBsonReader, - serializersModule: SerializersModule, - configuration: BsonConfiguration - ): BsonDocumentDecoder { - return if (hasJsonDecoder) JsonBsonDocumentDecoder(descriptor, reader, serializersModule, configuration) - else BsonDocumentDecoder(descriptor, reader, serializersModule, configuration) - } - - fun createBsonPolymorphicDecoder( - descriptor: SerialDescriptor, - reader: AbstractBsonReader, - serializersModule: SerializersModule, - configuration: BsonConfiguration - ): BsonPolymorphicDecoder { - return if (hasJsonDecoder) JsonBsonPolymorphicDecoder(descriptor, reader, serializersModule, configuration) - else BsonPolymorphicDecoder(descriptor, reader, serializersModule, configuration) - } - - fun createBsonMapDecoder( - descriptor: SerialDescriptor, - reader: AbstractBsonReader, - serializersModule: SerializersModule, - configuration: BsonConfiguration - ): BsonMapDecoder { - return if (hasJsonDecoder) JsonBsonMapDecoder(descriptor, reader, serializersModule, configuration) - else BsonMapDecoder(descriptor, reader, serializersModule, configuration) - } - } +public sealed interface BsonDecoder : Decoder, CompositeDecoder { /** @return the decoded ObjectId */ - fun decodeObjectId(): ObjectId + public fun decodeObjectId(): ObjectId /** @return the decoded BsonValue */ - fun decodeBsonValue(): BsonValue + public fun decodeBsonValue(): BsonValue } @OptIn(ExperimentalSerializationApi::class) @@ -325,7 +263,7 @@ internal open class BsonPolymorphicDecoder( it.reset() mark = null } - return deserializer.deserialize(BsonDecoder.createBsonDecoder(reader, serializersModule, configuration)) + return deserializer.deserialize(createBsonDecoder(reader, serializersModule, configuration)) } override fun decodeElementIndex(descriptor: SerialDescriptor): Int { diff --git a/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonEncoder.kt b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonEncoder.kt index 899b1b7a98..1470bbb76a 100644 --- a/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonEncoder.kt +++ b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/BsonEncoder.kt @@ -39,43 +39,21 @@ import org.bson.types.ObjectId * For custom serialization handlers */ @ExperimentalSerializationApi -internal sealed interface BsonEncoder : Encoder, CompositeEncoder { - - /** Factory helper for creating concrete BsonEncoder implementations */ - companion object { - @Suppress("SwallowedException") - private val hasJsonEncoder: Boolean by lazy { - try { - Class.forName("kotlinx.serialization.json.JsonEncoder") - true - } catch (e: ClassNotFoundException) { - false - } - } - - fun createBsonEncoder( - writer: BsonWriter, - serializersModule: SerializersModule, - configuration: BsonConfiguration - ): BsonEncoder { - return if (hasJsonEncoder) JsonBsonEncoder(writer, serializersModule, configuration) - else BsonEncoderImpl(writer, serializersModule, configuration) - } - } +public sealed interface BsonEncoder : Encoder, CompositeEncoder { /** * Encodes an ObjectId * * @param value the ObjectId */ - fun encodeObjectId(value: ObjectId) + public fun encodeObjectId(value: ObjectId) /** * Encodes a BsonValue * * @param value the BsonValue */ - fun encodeBsonValue(value: BsonValue) + public fun encodeBsonValue(value: BsonValue) } /** diff --git a/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/KotlinSerializerCodec.kt b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/KotlinSerializerCodec.kt index 41e674568a..0c7491b227 100644 --- a/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/KotlinSerializerCodec.kt +++ b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/KotlinSerializerCodec.kt @@ -34,6 +34,8 @@ import org.bson.codecs.Codec import org.bson.codecs.DecoderContext import org.bson.codecs.EncoderContext import org.bson.codecs.configuration.CodecConfigurationException +import org.bson.codecs.kotlinx.utils.BsonCodecUtils.createBsonDecoder +import org.bson.codecs.kotlinx.utils.BsonCodecUtils.createBsonEncoder import org.bson.codecs.pojo.annotations.BsonCreator import org.bson.codecs.pojo.annotations.BsonDiscriminator import org.bson.codecs.pojo.annotations.BsonExtraElements @@ -172,13 +174,13 @@ private constructor( } override fun encode(writer: BsonWriter, value: T, encoderContext: EncoderContext) { - serializer.serialize(BsonEncoder.createBsonEncoder(writer, serializersModule, bsonConfiguration), value) + serializer.serialize(createBsonEncoder(writer, serializersModule, bsonConfiguration), value) } override fun getEncoderClass(): Class = kClass.java override fun decode(reader: BsonReader, decoderContext: DecoderContext): T { require(reader is AbstractBsonReader) - return serializer.deserialize(BsonDecoder.createBsonDecoder(reader, serializersModule, bsonConfiguration)) + return serializer.deserialize(createBsonDecoder(reader, serializersModule, bsonConfiguration)) } } diff --git a/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/utils/BsonCodecUtils.kt b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/utils/BsonCodecUtils.kt new file mode 100644 index 0000000000..eabfebc583 --- /dev/null +++ b/bson-kotlinx/src/main/kotlin/org/bson/codecs/kotlinx/utils/BsonCodecUtils.kt @@ -0,0 +1,119 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.bson.codecs.kotlinx.utils + +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.modules.SerializersModule +import org.bson.AbstractBsonReader +import org.bson.BsonWriter +import org.bson.codecs.kotlinx.BsonArrayDecoder +import org.bson.codecs.kotlinx.BsonConfiguration +import org.bson.codecs.kotlinx.BsonDecoder +import org.bson.codecs.kotlinx.BsonDecoderImpl +import org.bson.codecs.kotlinx.BsonDocumentDecoder +import org.bson.codecs.kotlinx.BsonEncoder +import org.bson.codecs.kotlinx.BsonEncoderImpl +import org.bson.codecs.kotlinx.BsonMapDecoder +import org.bson.codecs.kotlinx.BsonPolymorphicDecoder +import org.bson.codecs.kotlinx.JsonBsonArrayDecoder +import org.bson.codecs.kotlinx.JsonBsonDecoderImpl +import org.bson.codecs.kotlinx.JsonBsonDocumentDecoder +import org.bson.codecs.kotlinx.JsonBsonEncoder +import org.bson.codecs.kotlinx.JsonBsonMapDecoder +import org.bson.codecs.kotlinx.JsonBsonPolymorphicDecoder + +@ExperimentalSerializationApi +internal object BsonCodecUtils { + + @Suppress("SwallowedException") + private val hasJsonEncoder: Boolean by lazy { + try { + Class.forName("kotlinx.serialization.json.JsonEncoder") + true + } catch (e: ClassNotFoundException) { + false + } + } + + @Suppress("SwallowedException") + private val hasJsonDecoder: Boolean by lazy { + try { + Class.forName("kotlinx.serialization.json.JsonDecoder") + true + } catch (e: ClassNotFoundException) { + false + } + } + + internal fun createBsonEncoder( + writer: BsonWriter, + serializersModule: SerializersModule, + configuration: BsonConfiguration + ): BsonEncoder { + return if (hasJsonEncoder) JsonBsonEncoder(writer, serializersModule, configuration) + else BsonEncoderImpl(writer, serializersModule, configuration) + } + + internal fun createBsonDecoder( + reader: AbstractBsonReader, + serializersModule: SerializersModule, + configuration: BsonConfiguration + ): BsonDecoder { + return if (hasJsonDecoder) JsonBsonDecoderImpl(reader, serializersModule, configuration) + else BsonDecoderImpl(reader, serializersModule, configuration) + } + + internal fun createBsonArrayDecoder( + descriptor: SerialDescriptor, + reader: AbstractBsonReader, + serializersModule: SerializersModule, + configuration: BsonConfiguration + ): BsonArrayDecoder { + return if (hasJsonDecoder) JsonBsonArrayDecoder(descriptor, reader, serializersModule, configuration) + else BsonArrayDecoder(descriptor, reader, serializersModule, configuration) + } + + internal fun createBsonDocumentDecoder( + descriptor: SerialDescriptor, + reader: AbstractBsonReader, + serializersModule: SerializersModule, + configuration: BsonConfiguration + ): BsonDocumentDecoder { + return if (hasJsonDecoder) JsonBsonDocumentDecoder(descriptor, reader, serializersModule, configuration) + else BsonDocumentDecoder(descriptor, reader, serializersModule, configuration) + } + + internal fun createBsonPolymorphicDecoder( + descriptor: SerialDescriptor, + reader: AbstractBsonReader, + serializersModule: SerializersModule, + configuration: BsonConfiguration + ): BsonPolymorphicDecoder { + return if (hasJsonDecoder) JsonBsonPolymorphicDecoder(descriptor, reader, serializersModule, configuration) + else BsonPolymorphicDecoder(descriptor, reader, serializersModule, configuration) + } + + internal fun createBsonMapDecoder( + descriptor: SerialDescriptor, + reader: AbstractBsonReader, + serializersModule: SerializersModule, + configuration: BsonConfiguration + ): BsonMapDecoder { + return if (hasJsonDecoder) JsonBsonMapDecoder(descriptor, reader, serializersModule, configuration) + else BsonMapDecoder(descriptor, reader, serializersModule, configuration) + } +}