
commonMain.dk.cachet.carp.common.infrastructure.serialization.UnknownDeviceSerializers.kt Maven / Gradle / Ivy
package dk.cachet.carp.common.infrastructure.serialization
import dk.cachet.carp.common.application.Trilean
import dk.cachet.carp.common.application.data.DataType
import dk.cachet.carp.common.application.devices.AnyDeviceDescriptor
import dk.cachet.carp.common.application.devices.AnyMasterDeviceDescriptor
import dk.cachet.carp.common.application.devices.DeviceDescriptor
import dk.cachet.carp.common.application.devices.DeviceRegistration
import dk.cachet.carp.common.application.devices.DeviceRegistrationBuilder
import dk.cachet.carp.common.application.devices.MasterDeviceDescriptor
import dk.cachet.carp.common.application.sampling.SamplingConfiguration
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlin.reflect.KClass
/**
* A wrapper used to load extending types from [DeviceDescriptor] serialized as JSON which are unknown at runtime.
*/
@Serializable( DeviceDescriptorSerializer::class )
data class CustomDeviceDescriptor(
override val className: String,
override val jsonSource: String,
val serializer: Json
) : DeviceDescriptor>(), UnknownPolymorphicWrapper
{
override val roleName: String
override val defaultSamplingConfiguration: Map
// This information is not serialized. Therefore, the supported types are unknown.
override fun getSupportedDataTypes(): Set = emptySet()
init
{
val json = Json( serializer ) { ignoreUnknownKeys = true }
val baseMembers = json.decodeFromString( BaseMembers.serializer(), jsonSource )
roleName = baseMembers.roleName
defaultSamplingConfiguration = baseMembers.defaultSamplingConfiguration
}
override fun createDeviceRegistrationBuilder(): DeviceRegistrationBuilder =
throw UnsupportedOperationException( "The concrete type of this device is not known. Therefore, it is unknown which registration builder is required." )
override fun getRegistrationClass(): KClass = DeviceRegistration::class
/**
* For unknown types, it cannot be determined whether or not a given registration is valid.
*/
override fun isValidRegistration( registration: DeviceRegistration ) = Trilean.UNKNOWN
}
/**
* A wrapper used to load extending types from [MasterDeviceDescriptor] serialized as JSON which are unknown at runtime.
*/
@Serializable( MasterDeviceDescriptorSerializer::class )
data class CustomMasterDeviceDescriptor(
override val className: String,
override val jsonSource: String,
val serializer: Json
) : MasterDeviceDescriptor>(), UnknownPolymorphicWrapper
{
override val roleName: String
override val defaultSamplingConfiguration: Map
// This information is not serialized. Therefore, the supported types are unknown.
override fun getSupportedDataTypes(): Set = emptySet()
init
{
val json = Json( serializer ) { ignoreUnknownKeys = true }
val baseMembers = json.decodeFromString( BaseMembers.serializer(), jsonSource )
roleName = baseMembers.roleName
defaultSamplingConfiguration = baseMembers.defaultSamplingConfiguration
}
override fun createDeviceRegistrationBuilder(): DeviceRegistrationBuilder =
throw UnsupportedOperationException( "The concrete type of this device is not known. Therefore, it is unknown which registration builder is required." )
override fun getRegistrationClass(): KClass = DeviceRegistration::class
/**
* For unknown types, it cannot be determined whether or not a given registration is valid.
*/
override fun isValidRegistration( registration: DeviceRegistration ) = Trilean.UNKNOWN
}
@Serializable
private data class BaseMembers(
override val roleName: String,
override val defaultSamplingConfiguration: Map
) : DeviceDescriptor>()
{
override fun getSupportedDataTypes(): Set =
throw UnsupportedOperationException()
override fun createDeviceRegistrationBuilder(): DeviceRegistrationBuilder =
throw UnsupportedOperationException()
override fun getRegistrationClass(): KClass =
throw UnsupportedOperationException()
override fun isValidRegistration( registration: DeviceRegistration ): Trilean =
throw UnsupportedOperationException()
}
/**
* Custom serializer for [DeviceDescriptor] which enables deserializing types that are unknown at runtime, yet extend from [DeviceDescriptor].
*/
object DeviceDescriptorSerializer : UnknownPolymorphicSerializer( DeviceDescriptor::class, DeviceDescriptor::class, false )
{
override fun createWrapper( className: String, json: String, serializer: Json ): AnyDeviceDescriptor
{
val jsonObject = serializer.parseToJsonElement( json ) as JsonObject
val isMasterDevice = jsonObject.containsKey( AnyMasterDeviceDescriptor::isMasterDevice.name )
return if ( isMasterDevice )
{
CustomMasterDeviceDescriptor( className, json, serializer )
}
else
{
CustomDeviceDescriptor( className, json, serializer )
}
}
}
/**
* Custom serializer for [MasterDeviceDescriptor] which enables deserializing types that are unknown at runtime, yet extend from [MasterDeviceDescriptor].
*/
object MasterDeviceDescriptorSerializer : KSerializer
by createUnknownPolymorphicSerializer( { className, json, serializer -> CustomMasterDeviceDescriptor( className, json, serializer ) } )
/**
* A wrapper used to load extending types from [DeviceRegistration] serialized as JSON which are unknown at runtime.
*/
@Serializable( DeviceRegistrationSerializer::class )
data class CustomDeviceRegistration(
override val className: String,
override val jsonSource: String,
val serializer: Json
) : DeviceRegistration(), UnknownPolymorphicWrapper
{
@Serializable
private data class BaseMembers( override val deviceId: String ) : DeviceRegistration()
override val deviceId: String
init
{
val json = Json( serializer ) { ignoreUnknownKeys = true }
val baseMembers = json.decodeFromString( BaseMembers.serializer(), jsonSource )
deviceId = baseMembers.deviceId
}
}
/**
* Custom serializer for a [DeviceRegistration] which enables deserializing types that are unknown at runtime, yet extend from [DeviceRegistration].
*/
object DeviceRegistrationSerializer : KSerializer
by createUnknownPolymorphicSerializer( { className, json, serializer -> CustomDeviceRegistration( className, json, serializer ) } )
© 2015 - 2025 Weber Informatics LLC | Privacy Policy