mirror of
https://github.com/corda/corda.git
synced 2024-12-27 00:21:12 +00:00
Finalise which map containers to serialize
This commit is contained in:
parent
de05a11511
commit
d2933ca8a3
@ -18,18 +18,23 @@ class MapSerializer(val declaredType: ParameterizedType, factory: SerializerFact
|
|||||||
override val typeDescriptor = "$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}"
|
override val typeDescriptor = "$DESCRIPTOR_DOMAIN:${fingerprintForType(type, factory)}"
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val supportedTypes: Map<Class<out Any>, (Map<*, *>) -> Map<*, *>> = mapOf(
|
private val supportedTypes: Map<Class<out Any?>, (Map<*, *>) -> Map<*, *>> = mapOf(
|
||||||
|
// Interfaces
|
||||||
Map::class.java to { map -> map },
|
Map::class.java to { map -> map },
|
||||||
SortedMap::class.java to { map -> TreeMap(map) },
|
SortedMap::class.java to { map -> TreeMap(map) },
|
||||||
NavigableMap::class.java to { map -> TreeMap(map) },
|
NavigableMap::class.java to { map -> TreeMap(map) },
|
||||||
|
// Sub types
|
||||||
Dictionary::class.java to { map -> Hashtable(map) },
|
Dictionary::class.java to { map -> Hashtable(map) },
|
||||||
// concrete types for user convienience
|
AbstractMap::class.java to { map -> LinkedHashMap(map) },
|
||||||
HashMap::class.java to { map -> LinkedHashMap(map) },
|
// concrete types
|
||||||
LinkedHashMap::class.java to { map -> LinkedHashMap(map) },
|
LinkedHashMap::class.java to { map -> LinkedHashMap(map) },
|
||||||
TreeMap::class.java to { map -> TreeMap(map) },
|
TreeMap::class.java to { map -> TreeMap(map) },
|
||||||
Hashtable::class.java to { map -> Hashtable(map) }
|
Hashtable::class.java to { map -> Hashtable(map) },
|
||||||
|
WeakHashMap::class.java to { map -> WeakHashMap(map) }
|
||||||
|
// Explicitly disallowed
|
||||||
|
// - HashMap::class.java
|
||||||
|
// - EnumMap::class.java
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun findConcreteType(clazz: Class<*>): (Map<*, *>) -> Map<*, *> {
|
private fun findConcreteType(clazz: Class<*>): (Map<*, *>) -> Map<*, *> {
|
||||||
return supportedTypes[clazz] ?: throw NotSerializableException("Unsupported map type $clazz.")
|
return supportedTypes[clazz] ?: throw NotSerializableException("Unsupported map type $clazz.")
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ internal fun constructorForDeserialization(type: Type): KFunction<Any>? {
|
|||||||
val kotlinConstructors = clazz.kotlin.constructors
|
val kotlinConstructors = clazz.kotlin.constructors
|
||||||
val hasDefault = kotlinConstructors.any { it.parameters.isEmpty() }
|
val hasDefault = kotlinConstructors.any { it.parameters.isEmpty() }
|
||||||
for (kotlinConstructor in kotlinConstructors) {
|
for (kotlinConstructor in kotlinConstructors) {
|
||||||
|
println (kotlinConstructor)
|
||||||
if (preferredCandidate == null && kotlinConstructors.size == 1 && !hasDefault) {
|
if (preferredCandidate == null && kotlinConstructors.size == 1 && !hasDefault) {
|
||||||
preferredCandidate = kotlinConstructor
|
preferredCandidate = kotlinConstructor
|
||||||
} else if (preferredCandidate == null && kotlinConstructors.size == 2 && hasDefault && kotlinConstructor.parameters.isNotEmpty()) {
|
} else if (preferredCandidate == null && kotlinConstructors.size == 2 && hasDefault && kotlinConstructor.parameters.isNotEmpty()) {
|
||||||
@ -44,6 +45,7 @@ internal fun constructorForDeserialization(type: Type): KFunction<Any>? {
|
|||||||
throw NotSerializableException("More than one constructor for $clazz is annotated with @CordaConstructor.")
|
throw NotSerializableException("More than one constructor for $clazz is annotated with @CordaConstructor.")
|
||||||
}
|
}
|
||||||
preferredCandidate = kotlinConstructor
|
preferredCandidate = kotlinConstructor
|
||||||
|
println (" -> $preferredCandidate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return preferredCandidate ?: throw NotSerializableException("No constructor for deserialization found for $clazz.")
|
return preferredCandidate ?: throw NotSerializableException("No constructor for deserialization found for $clazz.")
|
||||||
|
@ -5,7 +5,8 @@ import java.util.*
|
|||||||
import org.apache.qpid.proton.codec.Data
|
import org.apache.qpid.proton.codec.Data
|
||||||
|
|
||||||
class DeserializeCollectionTests {
|
class DeserializeCollectionTests {
|
||||||
class TestSerializationOutput(
|
|
||||||
|
class TestSerializationOutput(
|
||||||
private val verbose: Boolean,
|
private val verbose: Boolean,
|
||||||
serializerFactory: SerializerFactory = SerializerFactory()) : SerializationOutput(serializerFactory) {
|
serializerFactory: SerializerFactory = SerializerFactory()) : SerializationOutput(serializerFactory) {
|
||||||
|
|
||||||
@ -32,6 +33,23 @@ class TestSerializationOutput(
|
|||||||
DeserializationInput(sf).deserialize(serialisedBytes)
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun abstractMapFromMapOf() {
|
||||||
|
data class C(val c: AbstractMap<String, Int>)
|
||||||
|
val c = C (mapOf("A" to 1, "B" to 2) as AbstractMap)
|
||||||
|
|
||||||
|
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
|
||||||
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun abstractMapFromTreeMap() {
|
||||||
|
data class C(val c: AbstractMap<String, Int>)
|
||||||
|
val c = C (TreeMap(mapOf("A" to 1, "B" to 2)))
|
||||||
|
|
||||||
|
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
|
||||||
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
|
}
|
||||||
@Test
|
@Test
|
||||||
fun sortedMapTest() {
|
fun sortedMapTest() {
|
||||||
data class C(val c: SortedMap<String, Int>)
|
data class C(val c: SortedMap<String, Int>)
|
||||||
@ -40,6 +58,15 @@ class TestSerializationOutput(
|
|||||||
DeserializationInput(sf).deserialize(serialisedBytes)
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun navigableMapTest() {
|
||||||
|
data class C(val c: NavigableMap<String, Int>)
|
||||||
|
val c = C(TreeMap (mapOf("A" to 1, "B" to 2)).descendingMap())
|
||||||
|
|
||||||
|
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
|
||||||
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun dictionaryTest() {
|
fun dictionaryTest() {
|
||||||
data class C(val c: Dictionary<String, Int>)
|
data class C(val c: Dictionary<String, Int>)
|
||||||
@ -51,17 +78,8 @@ class TestSerializationOutput(
|
|||||||
DeserializationInput(sf).deserialize(serialisedBytes)
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun navigableMapTest() {
|
|
||||||
data class C(val c: NavigableMap<String, Int>)
|
|
||||||
val c = C(TreeMap (mapOf("A" to 1, "B" to 3)).descendingMap())
|
|
||||||
|
|
||||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
|
|
||||||
DeserializationInput(sf).deserialize(serialisedBytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=java.lang.IllegalArgumentException::class)
|
@Test(expected=java.lang.IllegalArgumentException::class)
|
||||||
fun HashMapTest() {
|
fun hashMapTest() {
|
||||||
data class C(val c : HashMap<String, Int>)
|
data class C(val c : HashMap<String, Int>)
|
||||||
val c = C (HashMap (mapOf("A" to 1, "B" to 2)))
|
val c = C (HashMap (mapOf("A" to 1, "B" to 2)))
|
||||||
|
|
||||||
@ -69,6 +87,15 @@ class TestSerializationOutput(
|
|||||||
TestSerializationOutput(VERBOSE, sf).serialize(c)
|
TestSerializationOutput(VERBOSE, sf).serialize(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun weakHashMapTest() {
|
||||||
|
data class C(val c : WeakHashMap<String, Int>)
|
||||||
|
val c = C (WeakHashMap (mapOf("A" to 1, "B" to 2)))
|
||||||
|
|
||||||
|
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
|
||||||
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun concreteTreeMapTest() {
|
fun concreteTreeMapTest() {
|
||||||
data class C(val c: TreeMap<String, Int>)
|
data class C(val c: TreeMap<String, Int>)
|
||||||
@ -84,10 +111,6 @@ class TestSerializationOutput(
|
|||||||
val c = C (LinkedHashMap (mapOf("A" to 1, "B" to 2)))
|
val c = C (LinkedHashMap (mapOf("A" to 1, "B" to 2)))
|
||||||
|
|
||||||
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
|
val serialisedBytes = TestSerializationOutput(VERBOSE, sf).serialize(c)
|
||||||
val deserializedObj = DeserializationInput(sf).deserialize(serialisedBytes)
|
DeserializationInput(sf).deserialize(serialisedBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ class SerializationOutputTests {
|
|||||||
serdes(obj)
|
serdes(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = NotSerializableException::class)
|
@Test
|
||||||
fun `test TreeMap property`() {
|
fun `test TreeMap property`() {
|
||||||
val obj = TreeMapWrapper(TreeMap<Int, Foo>())
|
val obj = TreeMapWrapper(TreeMap<Int, Foo>())
|
||||||
obj.tree[456] = Foo("Fred", 123)
|
obj.tree[456] = Foo("Fred", 123)
|
||||||
|
Loading…
Reference in New Issue
Block a user