CORDA-3469: Allow EvolutionSerializer to handle boxed types becoming primitive. (#5766)

This commit is contained in:
Chris Rankin 2019-11-28 16:39:45 +00:00 committed by Rick Parker
parent f7328f18f4
commit 5ce1535ea5
3 changed files with 29 additions and 2 deletions

View File

@ -114,13 +114,17 @@ class DefaultEvolutionSerializerFactory(
// This includes assigning a primitive type to its equivalent "boxed" type. // This includes assigning a primitive type to its equivalent "boxed" type.
val evolverPropertyType = evolverProperty.type.observedType.asClass() val evolverPropertyType = evolverProperty.type.observedType.asClass()
evolverPropertyType.isAssignableFrom(propertyType) evolverPropertyType.isAssignableFrom(propertyType)
|| (propertyType.isPrimitive && evolverPropertyType.isAssignableFrom(primitiveBoxedTypes[propertyType] || (propertyType.isPrimitive && evolverPropertyType.isAssignableFrom(boxed(propertyType)))
?: throw IllegalStateException("Unknown primitive type '$propertyType'"))) || (evolverPropertyType.isPrimitive && boxed(evolverPropertyType).isAssignableFrom(propertyType))
} }
} }
} }
} }
private fun boxed(primitiveType: Class<*>): Class<*> {
return primitiveBoxedTypes[primitiveType] ?: throw IllegalStateException("Unknown primitive type '$primitiveType'")
}
private fun RemoteTypeInformation.Composable.validateEvolvability(localProperties: Map<PropertyName, LocalPropertyInformation>) { private fun RemoteTypeInformation.Composable.validateEvolvability(localProperties: Map<PropertyName, LocalPropertyInformation>) {
val remotePropertyNames = properties.keys val remotePropertyNames = properties.keys
val localPropertyNames = localProperties.keys val localPropertyNames = localProperties.keys

View File

@ -768,4 +768,27 @@ class EvolvabilityTests {
assertEquals(1, deserializedCC.a) assertEquals(1, deserializedCC.a)
assertEquals(42, deserializedCC.b) assertEquals(42, deserializedCC.b)
} }
@Test
fun addMandatoryFieldWithAltConstructorAndMakeExistingNullableIntFieldMandatory() {
val sf = testDefaultFactory()
val resource = "EvolvabilityTests.addMandatoryFieldWithAltConstructorAndMakeExistingNullableIntFieldMandatory"
// Original version of the class as it was serialised
// data class CC(val a: Int?)
// File(URI("$localPath/$resource")).writeBytes(SerializationOutput(sf).serialize(CC(null)).bytes)
data class CC(val a: Int, val b: Int) {
@DeprecatedConstructorForDeserialization(1)
@Suppress("unused")
constructor(a: Int?) : this(a ?: -1,42)
}
val url = EvolvabilityTests::class.java.getResource(resource) ?: fail("Not found!")
val sc2 = url.readBytes()
val deserializedCC = DeserializationInput(sf).deserialize(SerializedBytes<CC>(sc2))
assertEquals(-1, deserializedCC.a)
assertEquals(42, deserializedCC.b)
}
} }