Merge pull request #6042 from corda/chrisr3-djvm-generics

NOTICK: Better use of generics for DJVM Collection and Map serializers.
This commit is contained in:
Matthew Nesbit 2020-03-09 08:56:19 +00:00 committed by GitHub
commit 2887dd0c88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 41 deletions

View File

@ -1,14 +1,18 @@
package net.corda.serialization.djvm.deserializers
import net.corda.core.utilities.NonEmptySet
import java.util.Collections
import java.util.Collections.unmodifiableCollection
import java.util.Collections.unmodifiableList
import java.util.Collections.unmodifiableNavigableSet
import java.util.Collections.unmodifiableSet
import java.util.Collections.unmodifiableSortedSet
import java.util.NavigableSet
import java.util.SortedSet
import java.util.TreeSet
import java.util.function.Function
class CreateCollection : Function<Array<Any?>, Collection<Any?>> {
private val concreteConstructors: Map<Class<out Collection<*>>, (Array<Any?>) -> Collection<Any?>> = mapOf(
class CreateCollection : Function<Array<out Any?>, Collection<Any?>> {
private val concreteConstructors: Map<Class<out Collection<*>>, (Array<out Any?>) -> Collection<Any?>> = mapOf(
List::class.java to ::createList,
Set::class.java to ::createSet,
SortedSet::class.java to ::createSortedSet,
@ -17,34 +21,34 @@ class CreateCollection : Function<Array<Any?>, Collection<Any?>> {
NonEmptySet::class.java to ::createNonEmptySet
)
private fun createList(values: Array<Any?>): List<Any?> {
return Collections.unmodifiableList(values.toCollection(ArrayList()))
private fun createList(values: Array<out Any?>): List<Any?> {
return unmodifiableList(values.toCollection(ArrayList()))
}
private fun createSet(values: Array<Any?>): Set<Any?> {
return Collections.unmodifiableSet(values.toCollection(LinkedHashSet()))
private fun createSet(values: Array<out Any?>): Set<Any?> {
return unmodifiableSet(values.toCollection(LinkedHashSet()))
}
private fun createSortedSet(values: Array<Any?>): SortedSet<Any?> {
return Collections.unmodifiableSortedSet(values.toCollection(TreeSet()))
private fun createSortedSet(values: Array<out Any?>): SortedSet<Any?> {
return unmodifiableSortedSet(values.toCollection(TreeSet()))
}
private fun createNavigableSet(values: Array<Any?>): NavigableSet<Any?> {
return Collections.unmodifiableNavigableSet(values.toCollection(TreeSet()))
private fun createNavigableSet(values: Array<out Any?>): NavigableSet<Any?> {
return unmodifiableNavigableSet(values.toCollection(TreeSet()))
}
private fun createCollection(values: Array<Any?>): Collection<Any?> {
return Collections.unmodifiableCollection(values.toCollection(ArrayList()))
private fun createCollection(values: Array<out Any?>): Collection<Any?> {
return unmodifiableCollection(values.toCollection(ArrayList()))
}
private fun createNonEmptySet(values: Array<Any?>): NonEmptySet<Any?> {
private fun createNonEmptySet(values: Array<out Any?>): NonEmptySet<Any?> {
return NonEmptySet.copyOf(values.toCollection(ArrayList()))
}
@Suppress("unchecked_cast")
override fun apply(inputs: Array<Any?>): Collection<Any?> {
override fun apply(inputs: Array<out Any?>): Collection<Any?> {
val collectionClass = inputs[0] as Class<out Collection<Any?>>
val args = inputs[1] as Array<Any?>
val args = inputs[1] as Array<out Any?>
return concreteConstructors[collectionClass]?.invoke(args)!!
}
}

View File

@ -1,14 +1,16 @@
package net.corda.serialization.djvm.deserializers
import java.util.Collections
import java.util.Collections.unmodifiableMap
import java.util.Collections.unmodifiableNavigableMap
import java.util.Collections.unmodifiableSortedMap
import java.util.EnumMap
import java.util.NavigableMap
import java.util.SortedMap
import java.util.TreeMap
import java.util.function.Function
class CreateMap : Function<Array<Any>, Map<Any?, Any?>> {
private val concreteConstructors: Map<Class<out Map<*, *>>, (Array<Array<Any>>) -> Map<Any?, Any?>> = mapOf(
class CreateMap : Function<Array<out Any>, Map<Any?, Any?>> {
private val concreteConstructors: Map<Class<out Map<*, *>>, (Array<Array<out Any>>) -> Map<Any?, Any?>> = mapOf(
Map::class.java to ::createMap,
SortedMap::class.java to ::createSortedMap,
LinkedHashMap::class.java to ::createLinkedHashMap,
@ -17,36 +19,36 @@ class CreateMap : Function<Array<Any>, Map<Any?, Any?>> {
EnumMap::class.java to ::createEnumMap
)
private fun createMap(values: Array<Array<Any>>): Map<Any?, Any?> {
return Collections.unmodifiableMap(values.map { it[0] to it[1] }.toMap())
private fun createMap(values: Array<Array<out Any>>): Map<Any?, Any?> {
return unmodifiableMap(values.associate { it[0] to it[1] })
}
private fun createSortedMap(values: Array<Array<Any>>): SortedMap<Any?, out Any?> {
return Collections.unmodifiableSortedMap(createTreeMap(values))
private fun createSortedMap(values: Array<Array<out Any>>): SortedMap<Any?, out Any?> {
return unmodifiableSortedMap(createTreeMap(values))
}
private fun createNavigableMap(values: Array<Array<Any>>): NavigableMap<Any?, out Any?> {
return Collections.unmodifiableNavigableMap(createTreeMap(values))
private fun createNavigableMap(values: Array<Array<out Any>>): NavigableMap<Any?, out Any?> {
return unmodifiableNavigableMap(createTreeMap(values))
}
private fun createLinkedHashMap(values: Array<Array<Any>>): LinkedHashMap<Any?, out Any?> {
return values.map { it[0] to it[1] }.toMap(LinkedHashMap())
private fun createLinkedHashMap(values: Array<Array<out Any>>): LinkedHashMap<Any?, out Any?> {
return values.associateTo(LinkedHashMap()) { it[0] to it[1] }
}
private fun createTreeMap(values: Array<Array<Any>>): TreeMap<Any?, out Any?> {
return values.map { it[0] to it[1] }.toMap(TreeMap())
private fun createTreeMap(values: Array<Array<out Any>>): TreeMap<Any?, out Any?> {
return values.associateTo(TreeMap()) { it[0] to it[1] }
}
private fun createEnumMap(values: Array<Array<Any>>): Map<Any?, Any?> {
val map = values.map { it[0] to it[1] }.toMap()
private fun createEnumMap(values: Array<Array<out Any>>): Map<Any?, Any?> {
val map = values.associate { it[0] to it[1] }
@Suppress("unchecked_cast")
return EnumMap(map as Map<JustForCasting, Any?>) as Map<Any?, Any?>
}
@Suppress("unchecked_cast")
override fun apply(inputs: Array<Any>): Map<Any?, Any?> {
override fun apply(inputs: Array<out Any>): Map<Any?, Any?> {
val mapClass = inputs[0] as Class<out Map<Any?, Any?>>
val args = inputs[1] as Array<Array<Any>>
val args = inputs[1] as Array<Array<out Any>>
return concreteConstructors[mapClass]?.invoke(args)!!
}
}

View File

@ -4,8 +4,8 @@ import net.corda.serialization.internal.amqp.custom.OptionalSerializer.OptionalP
import java.util.Optional
import java.util.function.Function
class OptionalDeserializer : Function<OptionalProxy, Optional<Any>> {
override fun apply(proxy: OptionalProxy): Optional<Any> {
class OptionalDeserializer : Function<OptionalProxy, Optional<out Any>> {
override fun apply(proxy: OptionalProxy): Optional<out Any> {
return Optional.ofNullable(proxy.item)
}
}

View File

@ -30,8 +30,8 @@ class SandboxCollectionSerializer(
private val localFactory: LocalSerializerFactory
) : CustomSerializer.Implements<Any>(clazz = classLoader.toSandboxAnyClass(Collection::class.java)) {
@Suppress("unchecked_cast")
private val creator: Function<Array<Any>, out Any?>
= taskFactory.apply(CreateCollection::class.java) as Function<Array<Any>, out Any?>
private val creator: Function<Array<out Any>, out Any?>
= taskFactory.apply(CreateCollection::class.java) as Function<Array<out Any>, out Any?>
private val unsupportedTypes: Set<Class<Any>> = listOf(
EnumSet::class.java
@ -87,7 +87,7 @@ class SandboxCollectionSerializer(
private class ConcreteCollectionSerializer(
declaredType: ParameterizedType,
private val matchingType: Map.Entry<Class<Any>, Class<out Collection<*>>>,
private val creator: Function<Array<Any>, out Any?>,
private val creator: Function<Array<out Any>, out Any?>,
factory: LocalSerializerFactory
) : AMQPSerializer<Any> {
override val type: ParameterizedType = declaredType

View File

@ -30,8 +30,8 @@ class SandboxMapSerializer(
private val localFactory: LocalSerializerFactory
) : CustomSerializer.Implements<Any>(clazz = classLoader.toSandboxAnyClass(Map::class.java)) {
@Suppress("unchecked_cast")
private val creator: Function<Array<Any>, out Any?>
= taskFactory.apply(CreateMap::class.java) as Function<Array<Any>, out Any?>
private val creator: Function<Array<out Any>, out Any?>
= taskFactory.apply(CreateMap::class.java) as Function<Array<out Any>, out Any?>
// The order matters here - the first match should be the most specific one.
// Kotlin preserves the ordering for us by associating into a LinkedHashMap.
@ -77,7 +77,7 @@ class SandboxMapSerializer(
private class ConcreteMapSerializer(
declaredType: ParameterizedType,
private val matchingType: Map.Entry<Class<Any>, Class<out Map<*, *>>>,
private val creator: Function<Array<Any>, out Any?>,
private val creator: Function<Array<out Any>, out Any?>,
factory: LocalSerializerFactory
) : AMQPSerializer<Any> {
override val type: ParameterizedType = declaredType