Skip to content

Commit

Permalink
Added possibility to customize ObjectMapper's KotlinModule
Browse files Browse the repository at this point in the history
  • Loading branch information
slaha authored and zigzago committed Nov 9, 2022
1 parent f73e0b7 commit dad79bb
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
Expand Up @@ -28,13 +28,15 @@ import com.fasterxml.jackson.databind.MapperFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import com.fasterxml.jackson.module.kotlin.KotlinModule
import com.fasterxml.jackson.module.kotlin.kotlinModule
import com.mongodb.BasicDBObject
import com.mongodb.DBObject
import com.mongodb.DBRef
import org.bson.UuidRepresentation
import org.bson.types.ObjectId
import org.litote.jackson.registerModulesFromServiceLoader
import org.litote.kmongo.util.KotlinModuleConfiguration
import org.litote.kmongo.util.ObjectMappingConfiguration
import java.math.BigDecimal
import java.math.BigInteger
Expand All @@ -49,7 +51,7 @@ internal object ObjectMapperFactory {

fun createExtendedJsonObjectMapper(): ObjectMapper {
return ObjectMapper()
.registerKotlinModule()
.registerModule(kotlinModule(KotlinModuleConfiguration.kotlinModuleInitializer))
.registerModule(SetMappingModule())
.registerModule(ExtendedJsonModule())
.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true)
Expand All @@ -67,7 +69,7 @@ internal object ObjectMapperFactory {

private fun configureBson(mapper: ObjectMapper, uuidRepresentation: UuidRepresentation?): ObjectMapper {
return mapper.registerModule(de.undercouch.bson4jackson.BsonModule())
.registerKotlinModule()
.registerModule(kotlinModule(KotlinModuleConfiguration.kotlinModuleInitializer))
.registerModule(CustomJacksonModule)
.registerModule(SetMappingModule())
.registerModule(BsonModule(uuidRepresentation))
Expand All @@ -81,7 +83,6 @@ internal object ObjectMapperFactory {
fun createFilterIdObjectMapper(objectMapper: ObjectMapper): ObjectMapper {
return objectMapper.copy().registerModule(FilterIdModule())
}

}

private object CustomJacksonModule : SimpleModule() {
Expand Down
Expand Up @@ -20,10 +20,11 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include.ALWAYS
import com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL
import com.fasterxml.jackson.databind.Module
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
import org.bson.UuidRepresentation
import org.litote.kmongo.jackson.JacksonCodecProvider
import org.litote.kmongo.jackson.ObjectMapperFactory
import kotlin.LazyThreadSafetyMode.PUBLICATION
import org.litote.kmongo.util.KotlinModuleConfiguration.kotlinModuleInitializer

/**
* Configure the jackson mapper engine.
Expand All @@ -41,6 +42,19 @@ object KMongoJacksonFeature {
}
}

/**
* Configure the [KotlinModule] used by jackson mapper engine.
*
* Call the methods of this object *before* any call to [KMongoConfiguration] methods.
*/
object KotlinModuleConfiguration {

/**
* Function to customize [KotlinModule] used by KMongo.
*/
var kotlinModuleInitializer: KotlinModule.Builder.() -> Unit = { }
}

/**
* Use this class to customize the default behaviour of KMongo jackson bindings.
*/
Expand Down
Expand Up @@ -16,9 +16,11 @@

package org.litote.kmongo.jackson

import com.fasterxml.jackson.module.kotlin.KotlinFeature
import com.fasterxml.jackson.module.kotlin.readValue
import org.junit.Test
import org.litote.kmongo.util.KMongoConfiguration
import org.litote.kmongo.util.KotlinModuleConfiguration
import kotlin.test.assertEquals
import kotlin.test.assertTrue

Expand All @@ -29,6 +31,7 @@ class ObjectMapperFactoryTest {

data class T(val set:Set<String>, val mutableSet: MutableSet<String>)
data class M(val map:Map<String, Boolean>, val mutableMap: MutableMap<String, Boolean>)
object Singleton

@Test
fun `Set is deserialized as LinkedHashSet`() {
Expand All @@ -45,4 +48,18 @@ class ObjectMapperFactoryTest {
assertTrue { m.map is LinkedHashMap }
assertTrue { m.mutableMap is LinkedHashMap }
}

@Test
fun `Deserialized object is the same instance as serialized object`() {
try {
KotlinModuleConfiguration.kotlinModuleInitializer = { enable(KotlinFeature.SingletonSupport) }
KMongoConfiguration.resetConfiguration()
val m = KMongoConfiguration.extendedJsonMapper.writeValueAsString(Singleton)
val deserializedSingleton = KMongoConfiguration.extendedJsonMapper.readValue<Singleton>(m)
assertTrue { Singleton === deserializedSingleton }
} finally {
KotlinModuleConfiguration.kotlinModuleInitializer = { }
KMongoConfiguration.resetConfiguration()
}
}
}
16 changes: 16 additions & 0 deletions kmongo-kdoc/docs/object-mapping.md
Expand Up @@ -5,6 +5,22 @@ Query results are automatically mapped to objects.
Look at the [Quick Start related paragraph](https://litote.org/kmongo/quick-start/#object-mapping-engine)
in order to know how to select the object mapping engine.

## Configure ```KotlinModule```

The ```ObjectMapper``` used by KMongo uses a [jackson's KotlinModule](https://github.com/FasterXML/jackson-module-kotlin).
The module is created with default ```KotlinFeature```s.
To change configuration of the module, use ```KotlinModuleConfiguration``` object:

```kotlin
KotlinModuleConfiguration.kotlinModuleInitializer = {
// Configure `KotlinModule` using its `Builder` (which is referenced as `this`):
enable(KotlinFeature.SingletonSupport)
enable(KotlinFeature.StrictNullChecks)
...
}
KMongoConfiguration.resetConfiguration()
```

## Set your _id

To manage Mongo ```_id```, a class must have one ```_id``` property
Expand Down

0 comments on commit dad79bb

Please sign in to comment.