From be64c895158fd310c04c9069d1a74239dcd13c09 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Thu, 15 Aug 2019 14:53:15 +0100 Subject: [PATCH] Implement generic CustomerSerializers that create more specific AMQPSerializer instances at runtime. --- .../serialization/internal/amqp/CustomSerializer.kt | 2 ++ .../internal/amqp/CustomSerializerRegistry.kt | 13 ++++++++++--- .../internal/amqp/DeserializationInput.kt | 4 ++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializer.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializer.kt index d12495e4fd..8eb4c6c60a 100644 --- a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializer.kt +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializer.kt @@ -57,6 +57,8 @@ abstract class CustomSerializer : AMQPSerializer, SerializerFor { abstract fun writeDescribedObject(obj: T, data: Data, type: Type, output: SerializationOutput, context: SerializationContext) + open fun specialiseFor(declaredType: Type): AMQPSerializer? = this + /** * This custom serializer represents a sort of symbolic link from a subclass to a super class, where the super * class custom serializer is responsible for the "on the wire" format but we want to create a reference to the diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializerRegistry.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializerRegistry.kt index 48486315fa..4ef4fe2307 100644 --- a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializerRegistry.kt +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/CustomSerializerRegistry.kt @@ -129,7 +129,7 @@ class CachingCustomSerializerRegistry( customSerializer } } - + override fun findCustomSerializer(clazz: Class<*>, declaredType: Type): AMQPSerializer? { val typeIdentifier = CustomSerializerIdentifier( TypeIdentifier.forClass(clazz), @@ -173,7 +173,13 @@ class CachingCustomSerializerRegistry( throw IllegalCustomSerializerException(declaredSerializers.first(), clazz) } - return declaredSerializers.first() + return declaredSerializers.first().let { + if (it is CustomSerializer) { + it.specialiseFor(declaredType) + } else { + it + } + } } private val Class<*>.isCustomSerializationForbidden: Boolean get() = when { @@ -182,4 +188,5 @@ class CachingCustomSerializerRegistry( isAnnotationPresent(CordaSerializable::class.java) -> true else -> false } -} \ No newline at end of file +} + diff --git a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/DeserializationInput.kt b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/DeserializationInput.kt index 503d370fd6..c21050bc8d 100644 --- a/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/DeserializationInput.kt +++ b/serialization/src/main/kotlin/net/corda/serialization/internal/amqp/DeserializationInput.kt @@ -142,12 +142,12 @@ class DeserializationInput constructor( envelope) } - internal fun readObjectOrNull(obj: Any?, schema: SerializationSchemas, type: Type, context: SerializationContext + fun readObjectOrNull(obj: Any?, schema: SerializationSchemas, type: Type, context: SerializationContext ): Any? { return if (obj == null) null else readObject(obj, schema, type, context) } - internal fun readObject(obj: Any, schemas: SerializationSchemas, type: Type, context: SerializationContext): Any = + fun readObject(obj: Any, schemas: SerializationSchemas, type: Type, context: SerializationContext): Any = if (obj is DescribedType && ReferencedObject.DESCRIPTOR == obj.descriptor) { // It must be a reference to an instance that has already been read, cheaply and quickly returning it by reference. val objectIndex = (obj.described as UnsignedInteger).toInt()