Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.13 RC1] Deprecation fixes for KotlinModule and docs for KotlinFeature #477

Merged
merged 5 commits into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions release-notes/CREDITS-2.x
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Authors:

Contributors:

Róbert Papp (TWiStErRob@github)
* #477: KotlinFeature documentation & deprecation replacements

wrongwrong (k163377@github)
* #468: Improved support for value classes
(2.13)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,45 @@ package com.fasterxml.jackson.module.kotlin
import java.util.BitSet
import kotlin.math.pow

/**
* @see KotlinModule.Builder
*/
enum class KotlinFeature(val enabledByDefault: Boolean) {
/**
* This feature represents whether to deserialize `null` values for collection properties as empty collections.
*/
NullToEmptyCollection(enabledByDefault = false),

/**
* This feature represents whether to deserialize `null` values for a map property to an empty map object.
*/
NullToEmptyMap(enabledByDefault = false),

/**
* This feature represents whether to treat `null` values as absent when deserializing,
* thereby using the default value provided in Kotlin.
*/
NullIsSameAsDefault(enabledByDefault = false),

/**
* By default, there's no special handling of singletons (pre-2.10 behavior).
* Each time a Singleton object is deserialized a new instance is created.
*
* When this feature is enabled, it will deserialize then canonicalize (was the default in 2.10).
* Deserializing a singleton overwrites the value of the single instance.
*
* See [jackson-module-kotlin#225]: keep Kotlin singletons as singletons.
* @see com.fasterxml.jackson.module.kotlin.SingletonSupport
*/
SingletonSupport(enabledByDefault = false),

/**
* This feature represents whether to check deserialized collections.
*
* With this disabled, the default, collections which are typed to disallow null members (e.g. `List<String>`)
* may contain null values after deserialization.
* Enabling it protects against this but has significant performance impact.
*/
StrictNullChecks(enabledByDefault = false);

internal val bitSet: BitSet = 2.0.pow(ordinal).toInt().toBitSet()
Expand Down
135 changes: 95 additions & 40 deletions src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,21 @@ fun Class<*>.isKotlinClass(): Boolean {
* (e.g. List<String>) may contain null values after deserialization. Enabling it
* protects against this but has significant performance impact.
*/
class KotlinModule @Deprecated(level = DeprecationLevel.WARNING, message = "Use KotlinModule.Builder") constructor(
class KotlinModule @Deprecated(
level = DeprecationLevel.WARNING,
message = "Use KotlinModule.Builder instead of named constructor parameters.",
replaceWith = ReplaceWith(
"""KotlinModule.Builder()
.withReflectionCacheSize(reflectionCacheSize)
.configure(KotlinFeature.NullToEmptyCollection, nullToEmptyCollection)
.configure(KotlinFeature.NullToEmptyMap, nullToEmptyMap)
.configure(KotlinFeature.NullIsSameAsDefault, nullIsSameAsDefault)
.configure(KotlinFeature.SingletonSupport, singletonSupport)
.configure(KotlinFeature.StrictNullChecks, strictNullChecks)
.build()""",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
) constructor(
val reflectionCacheSize: Int = 512,
val nullToEmptyCollection: Boolean = false,
val nullToEmptyMap: Boolean = false,
Expand Down Expand Up @@ -129,100 +143,141 @@ class KotlinModule @Deprecated(level = DeprecationLevel.WARNING, message = "Use
KotlinFeature.values().filter { it.enabledByDefault }.forEach { or(it.bitSet) }
}

fun withReflectionCacheSize(reflectionCacheSize: Int) = apply {
fun withReflectionCacheSize(reflectionCacheSize: Int): Builder = apply {
this.reflectionCacheSize = reflectionCacheSize
}

fun enable(feature: KotlinFeature) = apply {
fun enable(feature: KotlinFeature): Builder = apply {
bitSet.or(feature.bitSet)
}

fun disable(feature: KotlinFeature) = apply {
fun disable(feature: KotlinFeature): Builder = apply {
bitSet.andNot(feature.bitSet)
}

fun configure(feature: KotlinFeature, enabled: Boolean) = when {
enabled -> enable(feature)
else -> disable(feature)
}
fun configure(feature: KotlinFeature, enabled: Boolean): Builder =
when {
enabled -> enable(feature)
else -> disable(feature)
}

fun isEnabled(feature: KotlinFeature): Boolean = bitSet.intersects(feature.bitSet)
fun isEnabled(feature: KotlinFeature): Boolean =
bitSet.intersects(feature.bitSet)

@Deprecated(
message = "Deprecated, use withReflectionCacheSize(reflectionCacheSize) instead.",
replaceWith = ReplaceWith("isEnabled(reflectionCacheSize)")
replaceWith = ReplaceWith("withReflectionCacheSize(reflectionCacheSize)")
)
fun reflectionCacheSize(reflectionCacheSize: Int) = apply {
this.reflectionCacheSize = reflectionCacheSize
}
fun reflectionCacheSize(reflectionCacheSize: Int): Builder =
withReflectionCacheSize(reflectionCacheSize)

@Deprecated(
message = "Deprecated, use isEnabled(NullToEmptyCollection) instead.",
replaceWith = ReplaceWith("isEnabled(NullToEmptyCollection)")
replaceWith = ReplaceWith(
"isEnabled(KotlinFeature.NullToEmptyCollection)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun getNullToEmptyCollection() = isEnabled(NullToEmptyCollection)
fun getNullToEmptyCollection(): Boolean =
isEnabled(NullToEmptyCollection)

@Deprecated(
message = "Deprecated, use configure(NullToEmptyCollection, enabled) instead.",
replaceWith = ReplaceWith("configure(NullToEmptyCollection, enabled)")
replaceWith = ReplaceWith(
"configure(KotlinFeature.NullToEmptyCollection, nullToEmptyCollection)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun nullToEmptyCollection(nullToEmptyCollection: Boolean) =
fun nullToEmptyCollection(nullToEmptyCollection: Boolean): Builder =
configure(NullToEmptyCollection, nullToEmptyCollection)

@Deprecated(
message = "Deprecated, use isEnabled(NullToEmptyMap) instead.",
replaceWith = ReplaceWith("isEnabled(NullToEmptyMap)")
replaceWith = ReplaceWith(
"isEnabled(KotlinFeature.NullToEmptyMap)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun getNullToEmptyMap() = isEnabled(NullToEmptyMap)
fun getNullToEmptyMap(): Boolean =
isEnabled(NullToEmptyMap)

@Deprecated(
message = "Deprecated, use configure(NullToEmptyMap, enabled) instead.",
replaceWith = ReplaceWith("configure(NullToEmptyMap, enabled)")
replaceWith = ReplaceWith(
"configure(KotlinFeature.NullToEmptyMap, nullToEmptyMap)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun nullToEmptyMap(nullToEmptyMap: Boolean) = configure(NullToEmptyMap, nullToEmptyMap)
fun nullToEmptyMap(nullToEmptyMap: Boolean): Builder =
configure(NullToEmptyMap, nullToEmptyMap)

@Deprecated(
message = "Deprecated, use isEnabled(NullIsSameAsDefault) instead.",
replaceWith = ReplaceWith("isEnabled(NullIsSameAsDefault)")
replaceWith = ReplaceWith(
"isEnabled(KotlinFeature.NullIsSameAsDefault)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun getNullIsSameAsDefault() = isEnabled(NullIsSameAsDefault)
fun getNullIsSameAsDefault(): Boolean =
isEnabled(NullIsSameAsDefault)

@Deprecated(
message = "Deprecated, use configure(NullIsSameAsDefault, enabled) instead.",
replaceWith = ReplaceWith("configure(NullIsSameAsDefault, enabled)")
replaceWith = ReplaceWith(
"configure(KotlinFeature.NullIsSameAsDefault, nullIsSameAsDefault)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun nullIsSameAsDefault(nullIsSameAsDefault: Boolean) = configure(NullIsSameAsDefault, nullIsSameAsDefault)
fun nullIsSameAsDefault(nullIsSameAsDefault: Boolean): Builder =
configure(NullIsSameAsDefault, nullIsSameAsDefault)

@Deprecated(
message = "Deprecated, use isEnabled(SingletonSupport) instead.",
replaceWith = ReplaceWith("isEnabled(SingletonSupport)")
replaceWith = ReplaceWith(
"isEnabled(KotlinFeature.SingletonSupport)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun getSingletonSupport() = when {
isEnabled(KotlinFeature.SingletonSupport) -> CANONICALIZE
else -> DISABLED
}
fun getSingletonSupport(): SingletonSupport =
when {
isEnabled(KotlinFeature.SingletonSupport) -> CANONICALIZE
else -> DISABLED
}

@Deprecated(
message = "Deprecated, use configure(SingletonSupport, enabled) instead.",
replaceWith = ReplaceWith("configure(SingletonSupport, enabled)")
replaceWith = ReplaceWith(
"configure(KotlinFeature.SingletonSupport, singletonSupport)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun singletonSupport(singletonSupport: SingletonSupport) = when (singletonSupport) {
CANONICALIZE -> enable(KotlinFeature.SingletonSupport)
else -> disable(KotlinFeature.SingletonSupport)
}
fun singletonSupport(singletonSupport: SingletonSupport): Builder =
when (singletonSupport) {
CANONICALIZE -> enable(KotlinFeature.SingletonSupport)
else -> disable(KotlinFeature.SingletonSupport)
}

@Deprecated(
message = "Deprecated, use isEnabled(StrictNullChecks) instead.",
replaceWith = ReplaceWith("isEnabled(StrictNullChecks)")
replaceWith = ReplaceWith(
"isEnabled(KotlinFeature.StrictNullChecks)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun getStrictNullChecks() = isEnabled(StrictNullChecks)
fun getStrictNullChecks(): Boolean =
isEnabled(StrictNullChecks)

@Deprecated(
message = "Deprecated, use configure(StrictNullChecks, enabled) instead.",
replaceWith = ReplaceWith("configure(StrictNullChecks, enabled)")
replaceWith = ReplaceWith(
"configure(KotlinFeature.StrictNullChecks, strictNullChecks)",
"com.fasterxml.jackson.module.kotlin.KotlinFeature"
)
)
fun strictNullChecks(strictNullChecks: Boolean) = configure(StrictNullChecks, strictNullChecks)
fun strictNullChecks(strictNullChecks: Boolean): Builder =
configure(StrictNullChecks, strictNullChecks)

fun build() = KotlinModule(this)
fun build(): KotlinModule =
KotlinModule(this)
}
}