diff options
Diffstat (limited to 'kvision-modules/kvision-server-spring-boot')
13 files changed, 365 insertions, 266 deletions
diff --git a/kvision-modules/kvision-server-spring-boot/build.gradle b/kvision-modules/kvision-server-spring-boot/build.gradle deleted file mode 100644 index c46a38b1..00000000 --- a/kvision-modules/kvision-server-spring-boot/build.gradle +++ /dev/null @@ -1,40 +0,0 @@ -apply plugin: 'kotlin-platform-jvm' -apply plugin: 'kotlinx-serialization' - -repositories { - mavenCentral() - jcenter() - maven { url = "https://dl.bintray.com/kotlin/kotlin-eap" } - maven { url = 'https://kotlin.bintray.com/kotlinx' } - maven { url = 'https://dl.bintray.com/rjaros/kotlin' } - maven { url = "https://repo.spring.io/milestone" } -} - -dependencies { - expectedBy project(":kvision-modules:kvision-common-types") - expectedBy project(":kvision-modules:kvision-common-remote") - expectedBy project(":kvision-modules:kvision-common-annotations") - compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion" - compile "org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$coroutinesVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion" - compile "org.springframework.boot:spring-boot-starter:$springBootVersion" - compile "org.springframework.boot:spring-boot-starter-webflux:$springBootVersion" - compile "org.springframework.boot:spring-boot-starter-security:$springBootVersion" - compile "org.springframework.data:spring-data-relational:$springDataRelationalVersion" - compile "com.fasterxml.jackson.module:jackson-module-kotlin:${jacksonModuleKotlinVersion}" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlinVersion" - testCompile project(":kvision-modules:kvision-common-types") - testCompile project(":kvision-modules:kvision-common-remote") - testCompile project(":kvision-modules:kvision-common-annotations") -} - -compileKotlin { - kotlinOptions { - freeCompilerArgs = ["-Xjsr305=strict"] - jvmTarget = "1.8" - } -} diff --git a/kvision-modules/kvision-server-spring-boot/build.gradle.kts b/kvision-modules/kvision-server-spring-boot/build.gradle.kts new file mode 100644 index 00000000..d24073d4 --- /dev/null +++ b/kvision-modules/kvision-server-spring-boot/build.gradle.kts @@ -0,0 +1,72 @@ +buildscript { + extra.set("production", (findProperty("prod") ?: findProperty("production") ?: "false") == "true") +} + +plugins { + kotlin("multiplatform") + id("kotlinx-serialization") + id("maven-publish") +} + +repositories() + +// Versions +val kotlinVersion: String by System.getProperties() +val serializationVersion: String by project +val coroutinesVersion: String by project +val springBootVersion: String by project +val springDataRelationalVersion: String by project +val jacksonModuleKotlinVersion: String by project + +kotlin { + kotlinJsTargets() + kotlinJvmTargets() + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin("stdlib-common")) + api(project(":kvision-modules:kvision-common-annotations")) + api(project(":kvision-modules:kvision-common-types")) + api(project(":kvision-modules:kvision-common-remote")) + api(project(":kvision-modules:kvision-common-remote")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion") + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") + } + } + val jvmMain by getting { + dependsOn(commonMain) + dependencies { + implementation(kotlin("stdlib")) + implementation(kotlin("stdlib-jdk7")) + implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) + api("org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serializationVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") + api("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$coroutinesVersion") + api("org.springframework.boot:spring-boot-starter:$springBootVersion") + api("org.springframework.boot:spring-boot-starter-webflux:$springBootVersion") + api("org.springframework.boot:spring-boot-starter-security:$springBootVersion") + api("org.springframework.data:spring-data-relational:$springDataRelationalVersion") + api("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonModuleKotlinVersion") + } + } + } +} + +publishing { + publications.withType<MavenPublication> { + if (name == "kotlinMultiplatform") artifactId = "kvision-server-spring-boot" + pom { + defaultPom() + } + } +} + +setupPublication() 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/commonMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt index 1d37ae51..67fb1de1 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/types/Decimal.kt +++ b/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt @@ -19,29 +19,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package pl.treksoft.kvision.types +package pl.treksoft.kvision.remote -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 +@OptIn(ExperimentalMultiplatform::class) +@OptionalExpectation +expect annotation class Id() -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() - } -} +@OptIn(ExperimentalMultiplatform::class) +@OptionalExpectation +expect annotation class Transient() diff --git a/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..19da13c0 --- /dev/null +++ b/kvision-modules/kvision-server-spring-boot/src/commonMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,122 @@ +/* + * 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.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +expect open class KVServiceManager<T : Any>(serviceClass: KClass<T>) { + + /** + * 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 + */ + protected inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * 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 + */ + protected inline fun <reified PAR, reified RET> bind( + noinline function: suspend T.(PAR) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * 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 + */ + protected inline fun <reified PAR1, reified PAR2, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * 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 + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * 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 + */ + protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, + method: HttpMethod = HttpMethod.POST, + route: String? = null + ) + + /** + * 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 + */ + protected 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 = HttpMethod.POST, + route: String? = null + ) + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + protected inline fun <reified RET> bindTabulatorRemote( + noinline function: suspend T.(Int?, Int?, List<RemoteFilter>?, List<RemoteSorter>?, String?) -> RemoteData<RET> + ) + + /** + * Binds a given function of the receiver as a web socket connection + * @param function a function of the receiver + */ + protected inline fun <reified PAR1 : Any, reified PAR2 : Any> bind( + noinline function: suspend T.(ReceiveChannel<PAR1>, SendChannel<PAR2>) -> Unit, + route: String? = null + ) +} diff --git a/kvision-modules/kvision-server-spring-boot/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt new file mode 100644 index 00000000..23da6ac5 --- /dev/null +++ b/kvision-modules/kvision-server-spring-boot/src/jsMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -0,0 +1,160 @@ +/* + * 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.channels.ReceiveChannel +import kotlinx.coroutines.channels.SendChannel +import kotlin.reflect.KClass + +/** + * Multiplatform service manager. + */ +actual open class KVServiceManager<T : Any> actual constructor(serviceClass: KClass<T>): KVServiceMgr<T> { + + protected val calls: MutableMap<String, Pair<String, HttpMethod>> = mutableMapOf() + var counter: Int = 0 + + /** + * 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 + */ + protected actual inline fun <reified RET> bind( + noinline function: suspend T.() -> RET, + method: HttpMethod, route: String? + ) { + val routeDef = route ?: "route${this::class.simpleName}${counter++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * 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 + */ + 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++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * 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 + */ + 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++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * 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 + */ + 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++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * 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 + */ + 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++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * 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 + */ + 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++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", method) + } + + /** + * Binds a given function of the receiver as a tabulator component source + * @param function a function of the receiver + */ + 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++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kv/$routeDef", HttpMethod.POST) + } + + /** + * Binds a given web socket connetion with a function of the receiver. + * @param function a function of the receiver + * @param route a web socket 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++}" + calls[function.toString().replace("\\s".toRegex(), "")] = Pair("/kvws/$routeDef", HttpMethod.POST) + } + + /** + * Returns the map of defined paths. + */ + override fun getCalls(): Map<String, Pair<String, HttpMethod>> = calls + +} 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/jvmMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt index 7de82631..7de82631 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Annotations.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/Annotations.kt 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/jvmMain/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt index 42c4107d..42c4107d 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVRouterConfiguration.kt 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/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt index 2ee939ef..4c1d8e6a 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVServiceManager.kt @@ -53,7 +53,7 @@ import kotlin.reflect.KClass /** * Multiplatform service manager for Spring Boot. */ -@UseExperimental(ExperimentalCoroutinesApi::class) +@OptIn(ExperimentalCoroutinesApi::class) @Suppress("LargeClass", "TooManyFunctions") actual open class KVServiceManager<T : Any> actual constructor(val serviceClass: KClass<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/jvmMain/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt index 2c74e611..3c0e4e99 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/KVWebSocketConfig.kt @@ -63,7 +63,9 @@ class KVWebSocketHandler( }.first() } - @UseExperimental(ExperimentalCoroutinesApi::class, FlowPreview::class) + @OptIn( + ExperimentalCoroutinesApi::class, FlowPreview::class + ) override fun handle(session: WebSocketSession): Mono<Void> { val handler = getHandler(session) val responseChannel = Channel<String>() 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/jvmMain/kotlin/pl/treksoft/kvision/remote/Security.kt index 7a9084dc..7a9084dc 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/Security.kt 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/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt index 63c5a9d1..63c5a9d1 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/kotlin/pl/treksoft/kvision/remote/SessionInterfaces.kt diff --git a/kvision-modules/kvision-server-spring-boot/src/main/resources/META-INF/spring.factories b/kvision-modules/kvision-server-spring-boot/src/jvmMain/resources/META-INF/spring.factories index 01084666..01084666 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/resources/META-INF/spring.factories +++ b/kvision-modules/kvision-server-spring-boot/src/jvmMain/resources/META-INF/spring.factories 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 - } - } -} |