aboutsummaryrefslogtreecommitdiff
path: root/kvision-modules/kvision-server-spring-boot/src/main/kotlin
diff options
context:
space:
mode:
authorRobert Jaros <rjaros@finn.pl>2020-03-11 16:18:17 +0100
committerRobert Jaros <rjaros@finn.pl>2020-03-11 16:18:17 +0100
commit9e243a469ae6544e8cf523ad09b959f541c3f565 (patch)
treebe9c7447e221af49180c9e98434df7f988b940b8 /kvision-modules/kvision-server-spring-boot/src/main/kotlin
parentec6084c42c13a621e17b17bd40d90b5c7879f0ec (diff)
downloadkvision-9e243a469ae6544e8cf523ad09b959f541c3f565.tar.gz
kvision-9e243a469ae6544e8cf523ad09b959f541c3f565.tar.bz2
kvision-9e243a469ae6544e8cf523ad09b959f541c3f565.zip
Upgrade to Kotlin 1.3.70 + other dependencies (Coroutinse, Serialization, Spring Boot)
Major refactoring of build architecture.
Diffstat (limited to 'kvision-modules/kvision-server-spring-boot/src/main/kotlin')
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt29
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt81
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt586
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt108
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt67
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt43
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Date.kt200
-rw-r--r--kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt47
8 files changed, 0 insertions, 1161 deletions
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt
deleted file mode 100644
index 7de82631..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.remote
-
-import org.springframework.data.annotation.Id
-import org.springframework.data.annotation.Transient
-
-actual typealias Id = Id
-
-actual typealias Transient = Transient
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt
deleted file mode 100644
index 42c4107d..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.remote
-
-import org.springframework.beans.factory.annotation.Value
-import org.springframework.context.ApplicationContext
-import org.springframework.context.annotation.Bean
-import org.springframework.context.annotation.Configuration
-import org.springframework.context.support.GenericApplicationContext
-import org.springframework.core.io.Resource
-import org.springframework.http.MediaType.TEXT_HTML
-import org.springframework.stereotype.Component
-import org.springframework.web.reactive.function.server.ServerRequest
-import org.springframework.web.reactive.function.server.ServerResponse
-import org.springframework.web.reactive.function.server.buildAndAwait
-import org.springframework.web.reactive.function.server.coRouter
-import org.springframework.web.reactive.function.server.router
-
-@Configuration
-open class KVRouterConfiguration {
- @Value("classpath:/public/index.html")
- private lateinit var indexHtml: Resource
-
- @Bean
- open fun kvRoutes(kvHandler: KVHandler) = coRouter {
- GET("/kv/**", kvHandler::handle)
- POST("/kv/**", kvHandler::handle)
- PUT("/kv/**", kvHandler::handle)
- DELETE("/kv/**", kvHandler::handle)
- OPTIONS("/kv/**", kvHandler::handle)
- }
-
- @Bean
- open fun indexRouter() = router {
- GET("/") {
- ok().contentType(TEXT_HTML).bodyValue(indexHtml)
- }
- }
-}
-
-@Component
-open class KVHandler(var services: List<KVServiceManager<*>>, var applicationContext: ApplicationContext) {
-
- open suspend fun handle(request: ServerRequest): ServerResponse {
- val routeUrl = request.path()
- val handler = services.mapNotNull {
- when (request.method()?.name) {
- "GET" -> it.getRequests[routeUrl]
- "POST" -> it.postRequests[routeUrl]
- "PUT" -> it.putRequests[routeUrl]
- "DELETE" -> it.deleteRequests[routeUrl]
- "OPTIONS" -> it.optionsRequests[routeUrl]
- else -> null
- }
- }.firstOrNull()
- return if (handler != null) {
- handler(request, applicationContext as GenericApplicationContext)
- } else {
- ServerResponse.notFound().buildAndAwait()
- }
- }
-}
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt
deleted file mode 100644
index 2ee939ef..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.remote
-
-import com.fasterxml.jackson.databind.module.SimpleModule
-import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
-import com.fasterxml.jackson.module.kotlin.readValue
-import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.ReceiveChannel
-import kotlinx.coroutines.channels.SendChannel
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.reactive.awaitSingle
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.springframework.context.ApplicationContext
-import org.springframework.web.reactive.function.server.ServerRequest
-import org.springframework.web.reactive.function.server.ServerResponse
-import org.springframework.web.reactive.function.server.awaitBody
-import org.springframework.web.reactive.function.server.bodyValueAndAwait
-import org.springframework.web.reactive.function.server.json
-import org.springframework.web.reactive.socket.WebSocketSession
-import pl.treksoft.kvision.types.*
-import java.math.BigDecimal
-import java.time.LocalDate
-import java.time.LocalDateTime
-import java.time.LocalTime
-import java.time.OffsetDateTime
-import java.time.OffsetTime
-import kotlin.reflect.KClass
-
-/**
- * Multiplatform service manager for Spring Boot.
- */
-@UseExperimental(ExperimentalCoroutinesApi::class)
-@Suppress("LargeClass", "TooManyFunctions")
-actual open class KVServiceManager<T : Any> actual constructor(val serviceClass: KClass<T>) {
-
- companion object {
- val LOG: Logger = LoggerFactory.getLogger(KVServiceManager::class.java.name)
- }
-
- val getRequests: MutableMap<String, suspend (ServerRequest, ApplicationContext) -> ServerResponse> =
- mutableMapOf()
- val postRequests: MutableMap<String, suspend (ServerRequest, ApplicationContext) -> ServerResponse> =
- mutableMapOf()
- val putRequests: MutableMap<String, suspend (ServerRequest, ApplicationContext) -> ServerResponse> =
- mutableMapOf()
- val deleteRequests: MutableMap<String, suspend (ServerRequest, ApplicationContext) -> ServerResponse> =
- mutableMapOf()
- val optionsRequests: MutableMap<String, suspend (ServerRequest, ApplicationContext) -> ServerResponse> =
- mutableMapOf()
- val webSocketsRequests: MutableMap<String, suspend (
- WebSocketSession, ApplicationContext, ReceiveChannel<String>, SendChannel<String>
- ) -> Unit> =
- mutableMapOf()
-
- val mapper = jacksonObjectMapper().apply {
- val module = SimpleModule()
- module.addSerializer(LocalDateTime::class.java, LocalDateTimeSerializer())
- module.addSerializer(LocalDate::class.java, LocalDateSerializer())
- module.addSerializer(LocalTime::class.java, LocalTimeSerializer())
- module.addSerializer(OffsetDateTime::class.java, OffsetDateTimeSerializer())
- module.addSerializer(OffsetTime::class.java, OffsetTimeSerializer())
- module.addSerializer(BigDecimal::class.java, BigDecimalSerializer())
- module.addDeserializer(LocalDateTime::class.java, LocalDateTimeDeserializer())
- module.addDeserializer(LocalDate::class.java, LocalDateDeserializer())
- module.addDeserializer(LocalTime::class.java, LocalTimeDeserializer())
- module.addDeserializer(OffsetDateTime::class.java, OffsetDateTimeDeserializer())
- module.addDeserializer(OffsetTime::class.java, OffsetTimeDeserializer())
- module.addDeserializer(BigDecimal::class.java, BigDecimalDeserializer())
- this.registerModule(module)
- }
- var counter: Int = 0
-
- /**
- * @suppress internal function
- */
- suspend fun initializeService(service: T, req: ServerRequest) {
- if (service is WithRequest) {
- service.serverRequest = req
- }
- if (service is WithWebSession) {
- val session = req.session().awaitSingle()
- service.webSession = session
- }
- if (service is WithPrincipal) {
- val principal = req.principal().awaitSingle()
- service.principal = principal
- }
- }
-
- /**
- * Binds a given route with a function of the receiver.
- * @param function a function of the receiver
- * @param method a HTTP method
- * @param route a route
- */
- @Suppress("TooGenericExceptionCaught")
- protected actual inline fun <reified RET> bind(
- noinline function: suspend T.() -> RET,
- method: HttpMethod, route: String?
- ) {
- val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- addRoute(method, "/kv/$routeDef") { req, ctx ->
- val service = ctx.getBean(serviceClass.java)
- initializeService(service, req)
- val jsonRpcRequest = if (method == HttpMethod.GET) {
- JsonRpcRequest(req.queryParam("id").orElse(null)?.toInt() ?: 0, "", listOf())
- } else {
- req.awaitBody()
- }
- try {
- val result = function.invoke(service)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- result = mapper.writeValueAsString(result)
- )
- )
- )
- } catch (e: Exception) {
- if (e !is ServiceException) LOG.error(e.message, e)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = e.message ?: "Error",
- exceptionType = e.javaClass.canonicalName
- )
- )
- )
- }
- }
- }
-
- /**
- * Binds a given route with a function of the receiver.
- * @param function a function of the receiver
- * @param method a HTTP method
- * @param route a route
- */
- @Suppress("TooGenericExceptionCaught")
- protected actual inline fun <reified PAR, reified RET> bind(
- noinline function: suspend T.(PAR) -> RET,
- method: HttpMethod, route: String?
- ) {
- if (method == HttpMethod.GET)
- throw UnsupportedOperationException("GET method is only supported for methods without parameters")
- val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- addRoute(method, "/kv/$routeDef") { req, ctx ->
- val service = ctx.getBean(serviceClass.java)
- initializeService(service, req)
- val jsonRpcRequest = req.awaitBody<JsonRpcRequest>()
- if (jsonRpcRequest.params.size == 1) {
- val param = getParameter<PAR>(jsonRpcRequest.params[0])
- try {
- val result = function.invoke(service, param)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- result = mapper.writeValueAsString(result)
- )
- )
- )
- } catch (e: Exception) {
- if (e !is ServiceException) LOG.error(e.message, e)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = e.message ?: "Error",
- exceptionType = e.javaClass.canonicalName
- )
- )
- )
- }
- } else {
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = "Invalid parameters"
- )
- )
- )
- }
- }
- }
-
- /**
- * Binds a given route with a function of the receiver.
- * @param function a function of the receiver
- * @param method a HTTP method
- * @param route a route
- */
- @Suppress("TooGenericExceptionCaught")
- protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind(
- noinline function: suspend T.(PAR1, PAR2) -> RET,
- method: HttpMethod, route: String?
- ) {
- if (method == HttpMethod.GET)
- throw UnsupportedOperationException("GET method is only supported for methods without parameters")
- val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- addRoute(method, "/kv/$routeDef") { req, ctx ->
- val service = ctx.getBean(serviceClass.java)
- initializeService(service, req)
- val jsonRpcRequest = req.awaitBody<JsonRpcRequest>()
- if (jsonRpcRequest.params.size == 2) {
- val param1 = getParameter<PAR1>(jsonRpcRequest.params[0])
- val param2 = getParameter<PAR2>(jsonRpcRequest.params[1])
- try {
- val result = function.invoke(service, param1, param2)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- result = mapper.writeValueAsString(result)
- )
- )
- )
- } catch (e: Exception) {
- if (e !is ServiceException) LOG.error(e.message, e)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = e.message ?: "Error",
- exceptionType = e.javaClass.canonicalName
- )
- )
- )
- }
- } else {
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = "Invalid parameters"
- )
- )
- )
- }
- }
- }
-
- /**
- * Binds a given route with a function of the receiver.
- * @param function a function of the receiver
- * @param method a HTTP method
- * @param route a route
- */
- @Suppress("TooGenericExceptionCaught")
- protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind(
- noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET,
- method: HttpMethod, route: String?
- ) {
- if (method == HttpMethod.GET)
- throw UnsupportedOperationException("GET method is only supported for methods without parameters")
- val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- addRoute(method, "/kv/$routeDef") { req, ctx ->
- val service = ctx.getBean(serviceClass.java)
- initializeService(service, req)
- val jsonRpcRequest = req.awaitBody<JsonRpcRequest>()
- @Suppress("MagicNumber")
- if (jsonRpcRequest.params.size == 3) {
- val param1 = getParameter<PAR1>(jsonRpcRequest.params[0])
- val param2 = getParameter<PAR2>(jsonRpcRequest.params[1])
- val param3 = getParameter<PAR3>(jsonRpcRequest.params[2])
- try {
- val result = function.invoke(service, param1, param2, param3)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- result = mapper.writeValueAsString(result)
- )
- )
- )
- } catch (e: Exception) {
- if (e !is ServiceException) LOG.error(e.message, e)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = e.message ?: "Error",
- exceptionType = e.javaClass.canonicalName
- )
- )
- )
- }
- } else {
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = "Invalid parameters"
- )
- )
- )
- }
- }
- }
-
- /**
- * Binds a given route with a function of the receiver.
- * @param function a function of the receiver
- * @param method a HTTP method
- * @param route a route
- */
- @Suppress("TooGenericExceptionCaught")
- protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind(
- noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET,
- method: HttpMethod, route: String?
- ) {
- if (method == HttpMethod.GET)
- throw UnsupportedOperationException("GET method is only supported for methods without parameters")
- val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- addRoute(method, "/kv/$routeDef") { req, ctx ->
- val service = ctx.getBean(serviceClass.java)
- initializeService(service, req)
- val jsonRpcRequest = req.awaitBody<JsonRpcRequest>()
- @Suppress("MagicNumber")
- if (jsonRpcRequest.params.size == 4) {
- val param1 = getParameter<PAR1>(jsonRpcRequest.params[0])
- val param2 = getParameter<PAR2>(jsonRpcRequest.params[1])
- val param3 = getParameter<PAR3>(jsonRpcRequest.params[2])
- val param4 = getParameter<PAR4>(jsonRpcRequest.params[3])
- try {
- val result = function.invoke(service, param1, param2, param3, param4)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- result = mapper.writeValueAsString(result)
- )
- )
- )
- } catch (e: Exception) {
- if (e !is ServiceException) LOG.error(e.message, e)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = e.message ?: "Error",
- exceptionType = e.javaClass.canonicalName
- )
- )
- )
- }
- } else {
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = "Invalid parameters"
- )
- )
- )
- }
- }
- }
-
- /**
- * Binds a given route with a function of the receiver.
- * @param function a function of the receiver
- * @param method a HTTP method
- * @param route a route
- */
- @Suppress("TooGenericExceptionCaught")
- protected actual inline fun <reified PAR1, reified PAR2, reified PAR3,
- reified PAR4, reified PAR5, reified RET> bind(
- noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET,
- method: HttpMethod, route: String?
- ) {
- if (method == HttpMethod.GET)
- throw UnsupportedOperationException("GET method is only supported for methods without parameters")
- val routeDef = route ?: "route${this::class.simpleName}${counter++}"
- addRoute(method, "/kv/$routeDef") { req, ctx ->
- val service = ctx.getBean(serviceClass.java)
- initializeService(service, req)
- val jsonRpcRequest = req.awaitBody<JsonRpcRequest>()
- @Suppress("MagicNumber")
- if (jsonRpcRequest.params.size == 5) {
- val param1 = getParameter<PAR1>(jsonRpcRequest.params[0])
- val param2 = getParameter<PAR2>(jsonRpcRequest.params[1])
- val param3 = getParameter<PAR3>(jsonRpcRequest.params[2])
- val param4 = getParameter<PAR4>(jsonRpcRequest.params[3])
- val param5 = getParameter<PAR5>(jsonRpcRequest.params[4])
- try {
- val result = function.invoke(service, param1, param2, param3, param4, param5)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- result = mapper.writeValueAsString(result)
- )
- )
- )
- } catch (e: Exception) {
- if (e !is ServiceException) LOG.error(e.message, e)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = e.message ?: "Error",
- exceptionType = e.javaClass.canonicalName
- )
- )
- )
- }
- } else {
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = "Invalid parameters"
- )
- )
- )
- }
- }
- }
-
- /**
- * Binds a given web socket connetion with a function of the receiver.
- * @param function a function of the receiver
- * @param route a route
- */
- protected actual inline fun <reified PAR1 : Any, reified PAR2 : Any> bind(
- noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit,
- route: String?
- ) {
- val routeDef = "route${this::class.simpleName}${counter++}"
- webSocketsRequests[routeDef] = { webSocketSession, ctx, incoming, outgoing ->
- val service = ctx.getBean(serviceClass.java)
- if (service is WithWebSocketSession) {
- service.webSocketSession = webSocketSession
- }
- if (service is WithPrincipal) {
- val principal = webSocketSession.handshakeInfo.principal.awaitSingle()
- service.principal = principal
- }
- val requestChannel = Channel<PAR1>()
- val responseChannel = Channel<PAR2>()
- coroutineScope {
- launch {
- for (p in incoming) {
- val jsonRpcRequest = getParameter<JsonRpcRequest>(p)
- if (jsonRpcRequest.params.size == 1) {
- val par = getParameter<PAR1>(jsonRpcRequest.params[0])
- requestChannel.send(par)
- }
- }
- requestChannel.close()
- }
- launch {
- for (p in responseChannel) {
- val text = mapper.writeValueAsString(
- JsonRpcResponse(
- id = 0,
- result = mapper.writeValueAsString(p)
- )
- )
- outgoing.send(text)
- }
- if (!incoming.isClosedForReceive) incoming.cancel()
- }
- launch(start = CoroutineStart.UNDISPATCHED) {
- function.invoke(service, requestChannel, responseChannel)
- if (!responseChannel.isClosedForReceive) responseChannel.close()
- }
- }
- }
- }
-
- /**
- * Binds a given function of the receiver as a tabulator component source
- * @param function a function of the receiver
- */
- @Suppress("TooGenericExceptionCaught")
- protected actual inline fun <reified RET> bindTabulatorRemote(
- noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET>
- ) {
- val routeDef = "route${this::class.simpleName}${counter++}"
- addRoute(HttpMethod.POST, "/kv/$routeDef") { req, ctx ->
- val service = ctx.getBean(serviceClass.java)
- initializeService(service, req)
- val jsonRpcRequest = req.awaitBody<JsonRpcRequest>()
- @Suppress("MagicNumber")
- if (jsonRpcRequest.params.size == 5) {
- val param1 = getParameter<Int?>(jsonRpcRequest.params[0])
- val param2 = getParameter<Int?>(jsonRpcRequest.params[1])
- val param3 = getParameter<List<RemoteFilter>?>(jsonRpcRequest.params[2])
- @Suppress("MagicNumber")
- val param4 = getParameter<List<RemoteSorter>?>(jsonRpcRequest.params[3])
- @Suppress("MagicNumber")
- val param5 = getParameter<String?>(jsonRpcRequest.params[4])
- try {
- val result = function.invoke(service, param1, param2, param3, param4, param5)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- result = mapper.writeValueAsString(result)
- )
- )
- )
- } catch (e: Exception) {
- if (e !is ServiceException) LOG.error(e.message, e)
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = e.message ?: "Error",
- exceptionType = e.javaClass.canonicalName
- )
- )
- )
- }
- } else {
- ServerResponse.ok().json().bodyValueAndAwait(
- mapper.writeValueAsString(
- JsonRpcResponse(
- id = jsonRpcRequest.id,
- error = "Invalid parameters"
- )
- )
- )
- }
- }
- }
-
- /**
- * @suppress internal function
- */
- fun addRoute(
- method: HttpMethod,
- path: String,
- handler: suspend (ServerRequest, ApplicationContext) -> ServerResponse
- ) {
- when (method) {
- HttpMethod.GET -> getRequests[path] = handler
- HttpMethod.POST -> postRequests[path] = handler
- HttpMethod.PUT -> putRequests[path] = handler
- HttpMethod.DELETE -> deleteRequests[path] = handler
- HttpMethod.OPTIONS -> optionsRequests[path] = handler
- }
- }
-
- /**
- * @suppress internal function
- */
- protected inline fun <reified T> getParameter(str: String?): T {
- return str?.let {
- if (T::class == String::class) {
- str as T
- } else {
- mapper.readValue(str)
- }
- } ?: null as T
- }
-}
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt
deleted file mode 100644
index 2c74e611..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.remote
-
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.FlowPreview
-import kotlinx.coroutines.async
-import kotlinx.coroutines.channels.Channel
-import kotlinx.coroutines.channels.ReceiveChannel
-import kotlinx.coroutines.channels.SendChannel
-import kotlinx.coroutines.coroutineScope
-import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.flow.consumeAsFlow
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.reactive.asFlow
-import kotlinx.coroutines.reactor.asFlux
-import kotlinx.coroutines.reactor.asMono
-import org.springframework.context.ApplicationContext
-import org.springframework.context.annotation.Bean
-import org.springframework.context.annotation.Configuration
-import org.springframework.web.reactive.HandlerMapping
-import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping
-import org.springframework.web.reactive.socket.WebSocketHandler
-import org.springframework.web.reactive.socket.WebSocketSession
-import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter
-import reactor.core.publisher.Mono
-import kotlin.coroutines.EmptyCoroutineContext
-
-class KVWebSocketHandler(
- private val services: List<KVServiceManager<*>>,
- private val applicationContext: ApplicationContext
-) : WebSocketHandler, CoroutineScope by CoroutineScope(Dispatchers.Default) {
-
- private fun getHandler(session: WebSocketSession): (suspend (
- WebSocketSession, ApplicationContext,
- ReceiveChannel<String>, SendChannel<String>
- ) -> Unit) {
- val uri = session.handshakeInfo.uri.toString()
- val route = uri.substring(uri.lastIndexOf('/') + 1)
- return services.mapNotNull {
- it.webSocketsRequests[route]
- }.first()
- }
-
- @UseExperimental(ExperimentalCoroutinesApi::class, FlowPreview::class)
- override fun handle(session: WebSocketSession): Mono<Void> {
- val handler = getHandler(session)
- val responseChannel = Channel<String>()
- val requestChannel = Channel<String>()
- val output = session.send(responseChannel.consumeAsFlow().asFlux().map(session::textMessage))
- val input = async {
- coroutineScope {
- launch {
- session.receive().map {
- it.payloadAsText
- }.asFlow().collect {
- requestChannel.send(it)
- }
- requestChannel.close()
- }
- launch {
- handler.invoke(session, applicationContext, requestChannel, responseChannel)
- if (!responseChannel.isClosedForReceive) responseChannel.close()
- session.close()
- }
- }
- }.asMono(EmptyCoroutineContext).then()
- return Mono.zip(input, output).then()
- }
-}
-
-@Configuration
-open class KVWebSocketConfig(
- private var services: List<KVServiceManager<*>>,
- private var applicationContext: ApplicationContext
-) {
-
- @Bean
- open fun handlerMapping(): HandlerMapping {
- val map = mapOf("/kvws/*" to KVWebSocketHandler(services, applicationContext))
- val order = -1
- return SimpleUrlHandlerMapping(map, order)
- }
-
- @Bean
- open fun handlerAdapter() = WebSocketHandlerAdapter()
-}
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt
deleted file mode 100644
index 7a9084dc..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.remote
-
-import org.springframework.http.HttpMethod
-import org.springframework.security.config.web.server.ServerHttpSecurity
-import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher
-import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers
-
-/**
- * A function to gather paths for spring security matchers.
- */
-@Suppress("SpreadOperator", "MaxLineLength")
-fun ServerHttpSecurity.AuthorizeExchangeSpec.serviceMatchers(vararg services: KVServiceManager<*>): ServerHttpSecurity.AuthorizeExchangeSpec.Access {
- return this.matchers(*getServerWebExchangeMatcher(*services))
-}
-
-/**
- * A function to gather paths for spring security matchers.
- */
-@Suppress("SpreadOperator")
-fun serviceMatchers(vararg services: KVServiceManager<*>): ServerWebExchangeMatcher {
- return ServerWebExchangeMatchers.matchers(*getServerWebExchangeMatcher(*services))
-}
-
-/**
- * A function to gather paths for spring security matchers.
- */
-@Suppress("SpreadOperator")
-fun getServerWebExchangeMatcher(vararg services: KVServiceManager<*>): Array<ServerWebExchangeMatcher> {
- val matchers = mutableListOf<ServerWebExchangeMatcher>()
- val getPaths = services.flatMap { it.getRequests.keys }.toTypedArray()
- if (getPaths.isNotEmpty()) matchers.add(ServerWebExchangeMatchers.pathMatchers(HttpMethod.GET, *getPaths))
- val postPaths = services.flatMap { it.postRequests.keys }.toTypedArray()
- if (postPaths.isNotEmpty()) matchers.add(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, *postPaths))
- val putPaths = services.flatMap { it.putRequests.keys }.toTypedArray()
- if (putPaths.isNotEmpty()) matchers.add(ServerWebExchangeMatchers.pathMatchers(HttpMethod.PUT, *putPaths))
- val deletePaths = services.flatMap { it.deleteRequests.keys }.toTypedArray()
- if (deletePaths.isNotEmpty()) matchers.add(ServerWebExchangeMatchers.pathMatchers(HttpMethod.DELETE, *deletePaths))
- val optionsPaths = services.flatMap { it.optionsRequests.keys }.toTypedArray()
- if (optionsPaths.isNotEmpty()) matchers.add(
- ServerWebExchangeMatchers.pathMatchers(
- HttpMethod.OPTIONS,
- *optionsPaths
- )
- )
- return matchers.toTypedArray()
-}
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt
deleted file mode 100644
index 63c5a9d1..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.remote
-
-import org.springframework.web.reactive.function.server.ServerRequest
-import org.springframework.web.reactive.socket.WebSocketSession
-import org.springframework.web.server.WebSession
-import java.security.Principal
-
-interface WithRequest {
- var serverRequest: ServerRequest
-}
-
-interface WithWebSession {
- var webSession: WebSession
-}
-
-interface WithPrincipal {
- var principal: Principal
-}
-
-interface WithWebSocketSession {
- var webSocketSession: WebSocketSession
-}
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Date.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
deleted file mode 100644
index 61f8ba58..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Date.kt
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.types
-
-import com.fasterxml.jackson.core.JsonGenerator
-import com.fasterxml.jackson.core.JsonParser
-import com.fasterxml.jackson.databind.DeserializationContext
-import com.fasterxml.jackson.databind.JsonDeserializer
-import com.fasterxml.jackson.databind.JsonSerializer
-import com.fasterxml.jackson.databind.SerializerProvider
-import java.io.IOException
-import java.time.LocalDate
-import java.time.LocalDateTime
-import java.time.LocalTime
-import java.time.OffsetDateTime
-import java.time.OffsetTime
-import java.time.format.DateTimeFormatter
-import java.time.format.DateTimeParseException
-
-actual typealias LocalDateTime = LocalDateTime
-
-actual typealias LocalDate = LocalDate
-
-actual typealias LocalTime = LocalTime
-
-actual typealias OffsetDateTime = OffsetDateTime
-
-actual typealias OffsetTime = OffsetTime
-
-fun String.toDateTimeF(): LocalDateTime = LocalDateTime.parse(this)
-
-fun String.toDateF(): LocalDate = LocalDate.parse(this)
-
-fun String.toTimeF(): LocalTime = LocalTime.parse(this)
-
-fun String.toOffsetDateTimeF(): OffsetDateTime = OffsetDateTime.parse(this)
-
-fun String.toOffsetTimeF(): OffsetTime = OffsetTime.parse(this)
-
-fun LocalDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
-
-fun LocalDate.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_DATE)
-
-fun LocalTime.toStringF(): String = this.format(DateTimeFormatter.ISO_LOCAL_TIME)
-
-fun OffsetDateTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
-
-fun OffsetTime.toStringF(): String = this.format(DateTimeFormatter.ISO_OFFSET_TIME)
-
-class LocalDateTimeSerializer : JsonSerializer<LocalDateTime>() {
- @Throws(IOException::class)
- override fun serialize(value: LocalDateTime, gen: JsonGenerator, provider: SerializerProvider) {
- try {
- val s = value.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
- gen.writeString(s)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- gen.writeString("")
- }
- }
-}
-
-class LocalDateTimeDeserializer : JsonDeserializer<LocalDateTime>() {
- @Throws(IOException::class)
- override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDateTime? {
- val str = p.text
- try {
- @Suppress("MagicNumber")
- return LocalDateTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- return null
- }
- }
-}
-
-class LocalDateSerializer : JsonSerializer<LocalDate>() {
- @Throws(IOException::class)
- override fun serialize(value: LocalDate, gen: JsonGenerator, provider: SerializerProvider) {
- try {
- val s = value.atStartOfDay().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
- gen.writeString(s)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- gen.writeString("")
- }
- }
-}
-
-class LocalDateDeserializer : JsonDeserializer<LocalDate>() {
- @Throws(IOException::class)
- override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalDate? {
- val str = p.text
- try {
- @Suppress("MagicNumber")
- return LocalDate.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- return null
- }
- }
-}
-
-class LocalTimeSerializer : JsonSerializer<LocalTime>() {
- @Throws(IOException::class)
- override fun serialize(value: LocalTime, gen: JsonGenerator, provider: SerializerProvider) {
- try {
- val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
- gen.writeString(s)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- gen.writeString("")
- }
- }
-}
-
-class LocalTimeDeserializer : JsonDeserializer<LocalTime>() {
- @Throws(IOException::class)
- override fun deserialize(p: JsonParser, ctx: DeserializationContext): LocalTime? {
- val str = p.text
- try {
- @Suppress("MagicNumber")
- return LocalTime.parse(str.dropLast(6), DateTimeFormatter.ISO_LOCAL_DATE_TIME)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- return null
- }
- }
-}
-
-class OffsetDateTimeSerializer : JsonSerializer<OffsetDateTime>() {
- @Throws(IOException::class)
- override fun serialize(value: OffsetDateTime, gen: JsonGenerator, provider: SerializerProvider) {
- try {
- val s = value.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
- gen.writeString(s)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- gen.writeString("")
- }
- }
-}
-
-class OffsetDateTimeDeserializer : JsonDeserializer<OffsetDateTime>() {
- @Throws(IOException::class)
- override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetDateTime? {
- val str = p.text
- return try {
- OffsetDateTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- null
- }
- }
-}
-
-class OffsetTimeSerializer : JsonSerializer<OffsetTime>() {
- @Throws(IOException::class)
- override fun serialize(value: OffsetTime, gen: JsonGenerator, provider: SerializerProvider) {
- try {
- val s = value.atDate(LocalDate.now()).format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
- gen.writeString(s)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- gen.writeString("")
- }
- }
-}
-
-class OffsetTimeDeserializer : JsonDeserializer<OffsetTime>() {
- @Throws(IOException::class)
- override fun deserialize(p: JsonParser, ctx: DeserializationContext): OffsetTime? {
- val str = p.text
- return try {
- OffsetTime.parse(str, DateTimeFormatter.ISO_OFFSET_DATE_TIME)
- } catch (e: DateTimeParseException) {
- System.err.println(e)
- null
- }
- }
-}
diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt
deleted file mode 100644
index 1d37ae51..00000000
--- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2017-present Robert Jaros
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package pl.treksoft.kvision.types
-
-import com.fasterxml.jackson.core.JsonGenerator
-import com.fasterxml.jackson.core.JsonParser
-import com.fasterxml.jackson.databind.DeserializationContext
-import com.fasterxml.jackson.databind.JsonDeserializer
-import com.fasterxml.jackson.databind.JsonSerializer
-import com.fasterxml.jackson.databind.SerializerProvider
-import java.io.IOException
-import java.math.BigDecimal
-
-actual typealias Decimal = BigDecimal
-
-class BigDecimalSerializer : JsonSerializer<BigDecimal>() {
- @Throws(IOException::class)
- override fun serialize(value: BigDecimal, gen: JsonGenerator, provider: SerializerProvider) {
- gen.writeNumber(value.toDouble())
- }
-}
-
-class BigDecimalDeserializer : JsonDeserializer<BigDecimal>() {
- @Throws(IOException::class)
- override fun deserialize(p: JsonParser, ctx: DeserializationContext): BigDecimal? {
- return p.doubleValue.toBigDecimal()
- }
-}