mirror of
https://github.com/corda/corda.git
synced 2025-04-15 06:56:59 +00:00
Allow custom serializers to be registered with type aliases for deserializing.
This commit is contained in:
parent
2dd1e21404
commit
8f0c7c947a
@ -29,6 +29,10 @@ abstract class CustomSerializer<T : Any> : AMQPSerializer<T>, SerializerFor {
|
||||
*/
|
||||
open val additionalSerializers: Iterable<CustomSerializer<out Any>> = emptyList()
|
||||
|
||||
/**
|
||||
* This custom serializer is also allowed to deserialize these classes.
|
||||
*/
|
||||
open val deserializationAliases: Set<Class<*>> = emptySet()
|
||||
|
||||
protected abstract val descriptor: Descriptor
|
||||
/**
|
||||
@ -110,7 +114,7 @@ abstract class CustomSerializer<T : Any> : AMQPSerializer<T>, SerializerFor {
|
||||
*/
|
||||
abstract class CustomSerializerImp<T : Any>(protected val clazz: Class<T>, protected val withInheritance: Boolean) : CustomSerializer<T>() {
|
||||
override val type: Type get() = clazz
|
||||
override val typeDescriptor: Symbol = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${AMQPTypeIdentifiers.nameForType(clazz)}")
|
||||
override val typeDescriptor: Symbol = typeDescriptorFor(clazz)
|
||||
override fun writeClassInfo(output: SerializationOutput) {}
|
||||
override val descriptor: Descriptor = Descriptor(typeDescriptor)
|
||||
override fun isSerializerFor(clazz: Class<*>): Boolean = if (withInheritance) this.clazz.isAssignableFrom(clazz) else this.clazz == clazz
|
||||
|
@ -84,7 +84,7 @@ class CachingCustomSerializerRegistry(
|
||||
}
|
||||
|
||||
private val customSerializersCache: MutableMap<CustomSerializerIdentifier, CustomSerializerLookupResult> = DefaultCacheProvider.createCache()
|
||||
private var customSerializers: List<SerializerFor> = emptyList()
|
||||
private val customSerializers: MutableList<SerializerFor> = mutableListOf()
|
||||
|
||||
/**
|
||||
* Register a custom serializer for any type that cannot be serialized or deserialized by the default serializer
|
||||
@ -93,7 +93,7 @@ class CachingCustomSerializerRegistry(
|
||||
override fun register(customSerializer: CustomSerializer<out Any>) {
|
||||
logger.trace("action=\"Registering custom serializer\", class=\"${customSerializer.type}\"")
|
||||
|
||||
if (!customSerializersCache.isEmpty()) {
|
||||
if (customSerializersCache.isNotEmpty()) {
|
||||
logger.warn("Attempting to register custom serializer $customSerializer.type} in an active cache." +
|
||||
"All serializers should be registered before the cache comes into use.")
|
||||
}
|
||||
@ -103,14 +103,23 @@ class CachingCustomSerializerRegistry(
|
||||
for (additional in customSerializer.additionalSerializers) {
|
||||
register(additional)
|
||||
}
|
||||
|
||||
for (alias in customSerializer.deserializationAliases) {
|
||||
val aliasDescriptor = typeDescriptorFor(alias)
|
||||
if (aliasDescriptor != customSerializer.typeDescriptor) {
|
||||
descriptorBasedSerializerRegistry[aliasDescriptor.toString()] = customSerializer
|
||||
}
|
||||
}
|
||||
|
||||
customSerializer
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun registerExternal(customSerializer: CorDappCustomSerializer) {
|
||||
logger.trace("action=\"Registering external serializer\", class=\"${customSerializer.type}\"")
|
||||
|
||||
if (!customSerializersCache.isEmpty()) {
|
||||
if (customSerializersCache.isNotEmpty()) {
|
||||
logger.warn("Attempting to register custom serializer ${customSerializer.type} in an active cache." +
|
||||
"All serializers must be registered before the cache comes into use.")
|
||||
}
|
||||
|
@ -9,12 +9,13 @@ import org.apache.qpid.proton.amqp.UnsignedInteger
|
||||
import org.apache.qpid.proton.amqp.UnsignedLong
|
||||
import org.apache.qpid.proton.codec.DescribedTypeConstructor
|
||||
import java.io.NotSerializableException
|
||||
import net.corda.serialization.internal.carpenter.Field as CarpenterField
|
||||
import net.corda.serialization.internal.carpenter.Schema as CarpenterSchema
|
||||
import java.lang.reflect.Type
|
||||
|
||||
const val DESCRIPTOR_DOMAIN: String = "net.corda"
|
||||
val amqpMagic = CordaSerializationMagic("corda".toByteArray() + byteArrayOf(1, 0))
|
||||
|
||||
fun typeDescriptorFor(type: Type): Symbol = Symbol.valueOf("$DESCRIPTOR_DOMAIN:${AMQPTypeIdentifiers.nameForType(type)}")
|
||||
|
||||
/**
|
||||
* This and the classes below are OO representations of the AMQP XML schema described in the specification. Their
|
||||
* [toString] representations generate the associated XML form.
|
||||
|
@ -92,7 +92,7 @@ object SerializerFactoryBuilder {
|
||||
customSerializerRegistry,
|
||||
onlyCustomSerializers)
|
||||
|
||||
val typeLoader = ClassCarpentingTypeLoader(
|
||||
val typeLoader: TypeLoader = ClassCarpentingTypeLoader(
|
||||
SchemaBuildingRemoteTypeCarpenter(classCarpenter),
|
||||
classCarpenter.classloader)
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
package net.corda.serialization.internal.model
|
||||
|
||||
import net.corda.core.serialization.ClassWhitelist
|
||||
import net.corda.serialization.internal.amqp.*
|
||||
import java.lang.reflect.*
|
||||
|
||||
/**
|
||||
@ -54,7 +52,7 @@ class ConfigurableLocalTypeModel(private val typeModelConfiguration: LocalTypeMo
|
||||
private val typeInformationCache = DefaultCacheProvider.createCache<TypeIdentifier, LocalTypeInformation>()
|
||||
|
||||
/**
|
||||
* We need to provide the [TypeInformationBuilder] with a temporary local cache, so that it doesn't leak
|
||||
* We need to provide the [LocalTypeInformationBuilder] with a temporary local cache, so that it doesn't leak
|
||||
* [LocalTypeInformation] with unpatched cycles into the global cache where other threads can access them
|
||||
* before we've patched the cycles up.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user