Add encoding and decoding to/from entity by json encoding/decoding
This commit is contained in:
parent
5da1559882
commit
f77f6b7211
@ -52,5 +52,7 @@ include(
|
||||
":controls-magix-client",
|
||||
":motors",
|
||||
":controls-xodus",
|
||||
":controls-mongo"
|
||||
":controls-mongo",
|
||||
":xodus-serialization"
|
||||
)
|
||||
include("xodus-serialization")
|
||||
|
20
xodus-serialization/build.gradle.kts
Normal file
20
xodus-serialization/build.gradle.kts
Normal file
@ -0,0 +1,20 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.gradle.jvm")
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
val xodusVersion = "1.3.232"
|
||||
|
||||
kscience {
|
||||
useSerialization {
|
||||
json()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.magix.magixApi)
|
||||
implementation(projects.controlsCore)
|
||||
implementation("org.jetbrains.xodus:xodus-entity-store:$xodusVersion")
|
||||
implementation("org.jetbrains.xodus:xodus-environment:$xodusVersion")
|
||||
implementation("org.jetbrains.xodus:xodus-vfs:$xodusVersion")
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package ru.mipt.npm.xodus.serialization.json
|
||||
|
||||
import jetbrains.exodus.entitystore.Entity
|
||||
import jetbrains.exodus.entitystore.StoreTransaction
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.serializer
|
||||
|
||||
internal fun StoreTransaction.decodeFromEntity(entity: Entity): JsonElement = buildJsonObject {
|
||||
entity.propertyNames.forEach { property ->
|
||||
entity.getProperty(property).let { value ->
|
||||
when (value) {
|
||||
is Number -> put(property, value)
|
||||
is Boolean -> put(property, value)
|
||||
is String -> put(property, value)
|
||||
else -> throw IllegalStateException("Unsupported type for primitive field")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entity.linkNames.forEach { link ->
|
||||
entity.getLinks(link).let { entities ->
|
||||
when (entities.size()) {
|
||||
1L -> entities.first?.let { put(link, decodeFromEntity(it)) }
|
||||
else -> {
|
||||
putJsonArray(link) {
|
||||
entities.forEach {
|
||||
add(decodeFromEntity(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T> StoreTransaction.decodeFromEntity(entity: Entity, deserializer: DeserializationStrategy<T>): T {
|
||||
val jsonElement = decodeFromEntity(entity)
|
||||
return Json.decodeFromJsonElement(deserializer, jsonElement)
|
||||
}
|
||||
|
||||
public inline fun <reified T> StoreTransaction.decodeFromEntity(entity: Entity): T = decodeFromEntity(entity, serializer())
|
@ -0,0 +1,58 @@
|
||||
package ru.mipt.npm.xodus.serialization.json
|
||||
|
||||
import jetbrains.exodus.entitystore.Entity
|
||||
import jetbrains.exodus.entitystore.StoreTransaction
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.serializer
|
||||
|
||||
internal fun StoreTransaction.encodeToEntity(jsonElement: JsonElement, entity: Entity) {
|
||||
when (jsonElement) {
|
||||
is JsonPrimitive -> throw IllegalStateException("Can't serialize primitive value to entity")
|
||||
is JsonArray -> throw IllegalStateException("Can't serialize array value to entity")
|
||||
is JsonObject -> {
|
||||
jsonElement.forEach { entry ->
|
||||
entry.value.let { value ->
|
||||
when(value) {
|
||||
is JsonPrimitive -> {
|
||||
if (value.isString) {
|
||||
entity.setProperty(entry.key, value.content)
|
||||
} else {
|
||||
(value.longOrNull ?: value.doubleOrNull ?: value.booleanOrNull)?.let {
|
||||
entity.setProperty(
|
||||
entry.key,
|
||||
it
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// считаем, что все элементы массива - JsonObject, иначе не можем напрямую сериализовать (надо придывать костыли???)
|
||||
is JsonArray -> {
|
||||
value.forEach { element ->
|
||||
val childEntity = newEntity("${entity.type}.${entry.key}")
|
||||
encodeToEntity(element, childEntity)
|
||||
entity.addLink(entry.key, childEntity)
|
||||
}
|
||||
}
|
||||
|
||||
is JsonObject -> {
|
||||
val childEntity = newEntity("${entity.type}.${entry.key}")
|
||||
encodeToEntity(value, childEntity)
|
||||
entity.setLink(entry.key, childEntity)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T> StoreTransaction.encodeToEntity(serializer: SerializationStrategy<T>, value: T, entityType: String): Entity {
|
||||
val entity: Entity = newEntity(entityType)
|
||||
encodeToEntity(Json.encodeToJsonElement(serializer, value), entity)
|
||||
return entity
|
||||
}
|
||||
|
||||
public inline fun <reified T> StoreTransaction.encodeToEntity(value: T, entityType: String): Entity =
|
||||
encodeToEntity(serializer(), value, entityType)
|
@ -0,0 +1,39 @@
|
||||
package ru.mipt.npm.xodus.serialization.json
|
||||
|
||||
import jetbrains.exodus.entitystore.PersistentEntityStores
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import ru.mipt.npm.controls.api.PropertyChangedMessage
|
||||
import ru.mipt.npm.magix.api.MagixMessage
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.names.Name
|
||||
import java.nio.file.Paths
|
||||
|
||||
internal fun main() {
|
||||
val expectedMessage = MagixMessage(
|
||||
"dataforge",
|
||||
"dataforge",
|
||||
PropertyChangedMessage(
|
||||
"acceleration",
|
||||
Meta {
|
||||
"x" put 3.0
|
||||
"y" put 9.0
|
||||
},
|
||||
Name.parse("virtual-car"),
|
||||
Name.parse("magix-virtual-car"),
|
||||
time = Instant.fromEpochMilliseconds(1337)
|
||||
),
|
||||
"magix-virtual-car",
|
||||
user = JsonObject(content = mapOf(Pair("name", JsonPrimitive("SCADA"))))
|
||||
)
|
||||
|
||||
val entityStore = PersistentEntityStores.newInstance(Paths.get("xodus_serialization").toString())
|
||||
entityStore.executeInTransaction { txn ->
|
||||
txn.encodeToEntity(expectedMessage, "MagixMessage")
|
||||
}
|
||||
|
||||
entityStore.executeInTransaction { txn ->
|
||||
txn.getAll("MagixMessage").first?.let { println(txn.decodeFromEntity<MagixMessage<PropertyChangedMessage>>(it) == expectedMessage) }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user