Created
August 17, 2021 14:53
-
-
Save pschichtel/830b7943ea43b7cb58cadd984b54b903 to your computer and use it in GitHub Desktop.
SuspendAwareKotlinParameterNameDiscoverer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.hibernate.validator.internal.engine.DefaultClockProvider | |
import org.springframework.core.LocalVariableTableParameterNameDiscoverer | |
import org.springframework.core.PrioritizedParameterNameDiscoverer | |
import org.springframework.core.StandardReflectionParameterNameDiscoverer | |
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean | |
import java.lang.reflect.Constructor | |
import java.lang.reflect.Method | |
import javax.validation.ClockProvider | |
import javax.validation.Configuration | |
import javax.validation.ParameterNameProvider | |
/** | |
* This class is part of the workaround for a bug in hibernate-validation. | |
* | |
* It post-processes the Hibernate configuration to use our customized parameter name discoverer. | |
* | |
* See: | |
* * Spring issue: https://github.com/spring-projects/spring-framework/issues/23499 | |
* * Hibernate issue: https://hibernate.atlassian.net/browse/HV-1638 | |
*/ | |
class CustomLocalValidatorFactoryBean : LocalValidatorFactoryBean() { | |
override fun getClockProvider(): ClockProvider = DefaultClockProvider.INSTANCE | |
override fun postProcessConfiguration(configuration: Configuration<*>) { | |
super.postProcessConfiguration(configuration) | |
val discoverer = PrioritizedParameterNameDiscoverer() | |
discoverer.addDiscoverer(SuspendAwareKotlinParameterNameDiscoverer()) | |
discoverer.addDiscoverer(StandardReflectionParameterNameDiscoverer()) | |
discoverer.addDiscoverer(LocalVariableTableParameterNameDiscoverer()) | |
val defaultProvider = configuration.defaultParameterNameProvider | |
configuration.parameterNameProvider(object : ParameterNameProvider { | |
override fun getParameterNames(constructor: Constructor<*>): List<String> { | |
val paramNames: Array<String>? = discoverer.getParameterNames(constructor) | |
return paramNames?.toList() ?: defaultProvider.getParameterNames(constructor) | |
} | |
override fun getParameterNames(method: Method): List<String> { | |
val paramNames: Array<String>? = discoverer.getParameterNames(method) | |
return paramNames?.toList() ?: defaultProvider.getParameterNames(method) | |
} | |
}) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.springframework.context.annotation.Configuration | |
import org.springframework.context.annotation.Primary | |
import org.springframework.context.annotation.Role | |
import org.springframework.context.annotation.Bean | |
import org.springframework.beans.factory.config.BeanDefinition | |
import org.springframework.boot.validation.MessageInterpolatorFactory | |
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean | |
@Configuration(proxyBeanMethods = false) | |
class SomeConfiguration { | |
/** | |
* This bean definition is part of the workaround for a bug in hibernate-validation. | |
* | |
* It replaces the default validator factory bean with ours that uses the customized parameter name discoverer. | |
* | |
* See: | |
* * Spring issue: https://github.com/spring-projects/spring-framework/issues/23499 | |
* * Hibernate issue: https://hibernate.atlassian.net/browse/HV-1638 | |
*/ | |
@Primary | |
@Bean | |
@Role(BeanDefinition.ROLE_INFRASTRUCTURE) | |
fun defaultValidator(): LocalValidatorFactoryBean { | |
val factoryBean = CustomLocalValidatorFactoryBean() | |
factoryBean.messageInterpolator = MessageInterpolatorFactory().getObject() | |
return factoryBean | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.springframework.core.KotlinReflectionParameterNameDiscoverer | |
import org.springframework.core.ParameterNameDiscoverer | |
import java.lang.reflect.Constructor | |
import java.lang.reflect.Method | |
import kotlin.reflect.jvm.kotlinFunction | |
/** | |
* This class is part of the workaround for a bug in hibernate-validation. | |
* | |
* It appends an additional (empty) parameter name in case of suspend functions | |
* | |
* See: | |
* * Spring issue: https://github.com/spring-projects/spring-framework/issues/23499 | |
* * Hibernate issue: https://hibernate.atlassian.net/browse/HV-1638 | |
*/ | |
class SuspendAwareKotlinParameterNameDiscoverer : ParameterNameDiscoverer { | |
private val defaultProvider = KotlinReflectionParameterNameDiscoverer() | |
override fun getParameterNames(constructor: Constructor<*>): Array<String>? = | |
defaultProvider.getParameterNames(constructor) | |
override fun getParameterNames(method: Method): Array<String>? { | |
val defaultNames = defaultProvider.getParameterNames(method) ?: return null | |
val function = method.kotlinFunction | |
return if (function != null && function.isSuspend) { | |
defaultNames + "" | |
} else defaultNames | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment