mirror of
https://github.com/corda/corda.git
synced 2024-12-20 13:33:12 +00:00
Review comments
* Move all alterations on the amqp schema object out of the actual amqp/Schema file and have them live in the carpenter as extension functions * Move carpenter exceptions to their own file * Rename the schema name corrupter to the name mangler * reduce whitespace * alter comment style
This commit is contained in:
parent
5ab26dd275
commit
86902e6356
@ -15,11 +15,8 @@ import java.lang.reflect.Type
|
|||||||
import java.lang.reflect.TypeVariable
|
import java.lang.reflect.TypeVariable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
import net.corda.core.serialization.carpenter.CarpenterSchemas
|
|
||||||
import net.corda.core.serialization.carpenter.Schema as CarpenterSchema
|
import net.corda.core.serialization.carpenter.Schema as CarpenterSchema
|
||||||
import net.corda.core.serialization.carpenter.Field as CarpenterField
|
import net.corda.core.serialization.carpenter.Field as CarpenterField
|
||||||
import net.corda.core.serialization.carpenter.CarpenterSchemaFactory
|
|
||||||
import net.corda.core.serialization.carpenter.FieldFactory
|
|
||||||
|
|
||||||
// TODO: get an assigned number as per AMQP spec
|
// TODO: get an assigned number as per AMQP spec
|
||||||
val DESCRIPTOR_TOP_32BITS: Long = 0xc0da0000
|
val DESCRIPTOR_TOP_32BITS: Long = 0xc0da0000
|
||||||
@ -29,24 +26,6 @@ val DESCRIPTOR_DOMAIN: String = "net.corda"
|
|||||||
// "corda" + majorVersionByte + minorVersionMSB + minorVersionLSB
|
// "corda" + majorVersionByte + minorVersionMSB + minorVersionLSB
|
||||||
val AmqpHeaderV1_0: OpaqueBytes = OpaqueBytes("corda\u0001\u0000\u0000".toByteArray())
|
val AmqpHeaderV1_0: OpaqueBytes = OpaqueBytes("corda\u0001\u0000\u0000".toByteArray())
|
||||||
|
|
||||||
private fun List<ClassLoader>.exists (clazz: String) =
|
|
||||||
this.find { try { it.loadClass(clazz); true } catch (e: ClassNotFoundException) { false } } != null
|
|
||||||
|
|
||||||
private fun List<ClassLoader>.loadIfExists (clazz: String) : Class<*> {
|
|
||||||
this.forEach {
|
|
||||||
try {
|
|
||||||
return it.loadClass(clazz)
|
|
||||||
} catch (e: ClassNotFoundException) {
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw ClassNotFoundException(clazz)
|
|
||||||
}
|
|
||||||
|
|
||||||
class UncarpentableException (name: String, field: String, type: String) :
|
|
||||||
Throwable ("Class $name is loadable yet contains field $field of unknown type $type")
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class wraps all serialized data, so that the schema can be carried along with it. We will provide various internal utilities
|
* This class wraps all serialized data, so that the schema can be carried along with it. We will provide various internal utilities
|
||||||
* to decompose and recompose with/without schema etc so that e.g. we can store objects with a (relationally) normalised out schema to
|
* to decompose and recompose with/without schema etc so that e.g. we can store objects with a (relationally) normalised out schema to
|
||||||
@ -111,18 +90,6 @@ data class Schema(val types: List<TypeNotation>) : DescribedType {
|
|||||||
override fun getDescribed(): Any = listOf(types)
|
override fun getDescribed(): Any = listOf(types)
|
||||||
|
|
||||||
override fun toString(): String = types.joinToString("\n")
|
override fun toString(): String = types.joinToString("\n")
|
||||||
|
|
||||||
fun carpenterSchema(loaders : List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader()))
|
|
||||||
: CarpenterSchemas
|
|
||||||
{
|
|
||||||
val rtn = CarpenterSchemas.newInstance()
|
|
||||||
|
|
||||||
types.filterIsInstance<CompositeType>().forEach {
|
|
||||||
it.carpenterSchema(classLoaders = loaders, carpenterSchemas = rtn)
|
|
||||||
}
|
|
||||||
|
|
||||||
return rtn
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Descriptor(val name: String?, val code: UnsignedLong? = null) : DescribedType {
|
data class Descriptor(val name: String?, val code: UnsignedLong? = null) : DescribedType {
|
||||||
@ -205,29 +172,6 @@ data class Field(val name: String, val type: String, val requires: List<String>,
|
|||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getTypeAsClass(
|
|
||||||
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader())
|
|
||||||
) = when (type) {
|
|
||||||
"int" -> Int::class.javaPrimitiveType!!
|
|
||||||
"string" -> String::class.java
|
|
||||||
"short" -> Short::class.javaPrimitiveType!!
|
|
||||||
"long" -> Long::class.javaPrimitiveType!!
|
|
||||||
"char" -> Char::class.javaPrimitiveType!!
|
|
||||||
"boolean" -> Boolean::class.javaPrimitiveType!!
|
|
||||||
"double" -> Double::class.javaPrimitiveType!!
|
|
||||||
"float" -> Float::class.javaPrimitiveType!!
|
|
||||||
"*" -> classLoaders.loadIfExists(requires[0])
|
|
||||||
else -> classLoaders.loadIfExists(type)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun validateType(
|
|
||||||
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader())
|
|
||||||
) = when (type) {
|
|
||||||
"int", "string", "short", "long", "char", "boolean", "double", "float" -> true
|
|
||||||
"*" -> classLoaders.exists(requires[0])
|
|
||||||
else -> classLoaders.exists (type)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun typeAsString() = if (type =="*") requires[0] else type
|
fun typeAsString() = if (type =="*") requires[0] else type
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,85 +238,6 @@ data class CompositeType(override val name: String, override val label: String?,
|
|||||||
sb.append("</type>")
|
sb.append("</type>")
|
||||||
return sb.toString()
|
return sb.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* if we can load the class then we MUST know about all of it's composite elements
|
|
||||||
*/
|
|
||||||
private fun validateKnown (
|
|
||||||
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader()))
|
|
||||||
{
|
|
||||||
fields.forEach {
|
|
||||||
if (!it.validateType(classLoaders)) throw UncarpentableException (name, it.name, it.type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* based upon this AMQP schema either
|
|
||||||
* a) add the corespending carpenter schema to the [carpenterSchemas] param
|
|
||||||
* b) add the class to the dependency tree in [carpenterSchemas] if it cannot be instantiated
|
|
||||||
* at this time
|
|
||||||
*
|
|
||||||
* @param classLoaders list of classLoaders, defaulting toe the system class loader, that might
|
|
||||||
* be used to load objects
|
|
||||||
* @param carpenterSchemas structure that holds the dependency tree and list of classes that
|
|
||||||
* need constructing
|
|
||||||
* @param force by default a schema is not added to [carpenterSchemas] if it already exists
|
|
||||||
* on the class path. For testing purposes schema generation can be forced
|
|
||||||
*/
|
|
||||||
fun carpenterSchema(
|
|
||||||
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader()),
|
|
||||||
carpenterSchemas : CarpenterSchemas,
|
|
||||||
force : Boolean = false)
|
|
||||||
{
|
|
||||||
/* first question, do we know about this type or not */
|
|
||||||
if (classLoaders.exists(name)) {
|
|
||||||
validateKnown(classLoaders)
|
|
||||||
|
|
||||||
if (!force) return
|
|
||||||
}
|
|
||||||
|
|
||||||
val providesList = mutableListOf<Class<*>>()
|
|
||||||
|
|
||||||
var isInterface = false
|
|
||||||
var isCreatable = true
|
|
||||||
|
|
||||||
provides.forEach {
|
|
||||||
if (name == it) {
|
|
||||||
isInterface = true
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
providesList.add (classLoaders.loadIfExists(it))
|
|
||||||
}
|
|
||||||
catch (e: ClassNotFoundException) {
|
|
||||||
carpenterSchemas.addDepPair(this, name, it)
|
|
||||||
|
|
||||||
isCreatable = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val m : MutableMap<String, CarpenterField> = mutableMapOf()
|
|
||||||
|
|
||||||
fields.forEach {
|
|
||||||
try {
|
|
||||||
m[it.name] = FieldFactory.newInstance(it.mandatory, it.name, it.getTypeAsClass(classLoaders))
|
|
||||||
}
|
|
||||||
catch (e: ClassNotFoundException) {
|
|
||||||
carpenterSchemas.addDepPair(this, name, it.typeAsString())
|
|
||||||
|
|
||||||
isCreatable = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCreatable) {
|
|
||||||
carpenterSchemas.carpenterSchemas.add (CarpenterSchemaFactory.newInstance(
|
|
||||||
name = name,
|
|
||||||
fields = m,
|
|
||||||
interfaces = providesList,
|
|
||||||
isInterface = isInterface))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data class RestrictedType(override val name: String, override val label: String?, override val provides: List<String>, val source: String, override val descriptor: Descriptor, val choices: List<Choice>) : TypeNotation() {
|
data class RestrictedType(override val name: String, override val label: String?, override val provides: List<String>, val source: String, override val descriptor: Descriptor, val choices: List<Choice>) : TypeNotation() {
|
||||||
|
@ -0,0 +1,127 @@
|
|||||||
|
package net.corda.core.serialization.carpenter
|
||||||
|
|
||||||
|
import net.corda.core.serialization.amqp.Schema as AMQPSchema
|
||||||
|
import net.corda.core.serialization.amqp.Field as AMQPField
|
||||||
|
import net.corda.core.serialization.amqp.CompositeType
|
||||||
|
|
||||||
|
fun AMQPSchema.carpenterSchema(
|
||||||
|
loaders : List<ClassLoader> = listOf<ClassLoader>(ClassLoader.getSystemClassLoader()))
|
||||||
|
: CarpenterSchemas {
|
||||||
|
val rtn = CarpenterSchemas.newInstance()
|
||||||
|
|
||||||
|
types.filterIsInstance<CompositeType>().forEach {
|
||||||
|
it.carpenterSchema(classLoaders = loaders, carpenterSchemas = rtn)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if we can load the class then we MUST know about all of it's composite elements
|
||||||
|
*/
|
||||||
|
private fun CompositeType.validateKnown (
|
||||||
|
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader())){
|
||||||
|
fields.forEach {
|
||||||
|
if (!it.validateType(classLoaders)) throw UncarpentableException (name, it.name, it.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* based upon this AMQP schema either
|
||||||
|
* a) add the corresponding carpenter schema to the [carpenterSchemas] param
|
||||||
|
* b) add the class to the dependency tree in [carpenterSchemas] if it cannot be instantiated
|
||||||
|
* at this time
|
||||||
|
*
|
||||||
|
* @param classLoaders list of classLoaders, defaulting toe the system class loader, that might
|
||||||
|
* be used to load objects
|
||||||
|
* @param carpenterSchemas structure that holds the dependency tree and list of classes that
|
||||||
|
* need constructing
|
||||||
|
* @param force by default a schema is not added to [carpenterSchemas] if it already exists
|
||||||
|
* on the class path. For testing purposes schema generation can be forced
|
||||||
|
*/
|
||||||
|
fun CompositeType.carpenterSchema(
|
||||||
|
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader()),
|
||||||
|
carpenterSchemas : CarpenterSchemas,
|
||||||
|
force : Boolean = false) {
|
||||||
|
if (classLoaders.exists(name)) {
|
||||||
|
validateKnown(classLoaders)
|
||||||
|
if (!force) return
|
||||||
|
}
|
||||||
|
|
||||||
|
val providesList = mutableListOf<Class<*>>()
|
||||||
|
|
||||||
|
var isInterface = false
|
||||||
|
var isCreatable = true
|
||||||
|
|
||||||
|
provides.forEach {
|
||||||
|
if (name == it) {
|
||||||
|
isInterface = true
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
providesList.add (classLoaders.loadIfExists(it))
|
||||||
|
}
|
||||||
|
catch (e: ClassNotFoundException) {
|
||||||
|
carpenterSchemas.addDepPair(this, name, it)
|
||||||
|
isCreatable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val m : MutableMap<String, Field> = mutableMapOf()
|
||||||
|
|
||||||
|
fields.forEach {
|
||||||
|
try {
|
||||||
|
m[it.name] = FieldFactory.newInstance(it.mandatory, it.name, it.getTypeAsClass(classLoaders))
|
||||||
|
}
|
||||||
|
catch (e: ClassNotFoundException) {
|
||||||
|
carpenterSchemas.addDepPair(this, name, it.typeAsString())
|
||||||
|
isCreatable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isCreatable) {
|
||||||
|
carpenterSchemas.carpenterSchemas.add (CarpenterSchemaFactory.newInstance(
|
||||||
|
name = name,
|
||||||
|
fields = m,
|
||||||
|
interfaces = providesList,
|
||||||
|
isInterface = isInterface))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AMQPField.getTypeAsClass(
|
||||||
|
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader())
|
||||||
|
) = when (type) {
|
||||||
|
"int" -> Int::class.javaPrimitiveType!!
|
||||||
|
"string" -> String::class.java
|
||||||
|
"short" -> Short::class.javaPrimitiveType!!
|
||||||
|
"long" -> Long::class.javaPrimitiveType!!
|
||||||
|
"char" -> Char::class.javaPrimitiveType!!
|
||||||
|
"boolean" -> Boolean::class.javaPrimitiveType!!
|
||||||
|
"double" -> Double::class.javaPrimitiveType!!
|
||||||
|
"float" -> Float::class.javaPrimitiveType!!
|
||||||
|
"*" -> classLoaders.loadIfExists(requires[0])
|
||||||
|
else -> classLoaders.loadIfExists(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AMQPField.validateType(
|
||||||
|
classLoaders: List<ClassLoader> = listOf<ClassLoader> (ClassLoader.getSystemClassLoader())
|
||||||
|
) = when (type) {
|
||||||
|
"int", "string", "short", "long", "char", "boolean", "double", "float" -> true
|
||||||
|
"*" -> classLoaders.exists(requires[0])
|
||||||
|
else -> classLoaders.exists (type)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<ClassLoader>.exists (clazz: String) =
|
||||||
|
this.find { try { it.loadClass(clazz); true } catch (e: ClassNotFoundException) { false } } != null
|
||||||
|
|
||||||
|
private fun List<ClassLoader>.loadIfExists (clazz: String) : Class<*> {
|
||||||
|
this.forEach {
|
||||||
|
try {
|
||||||
|
return it.loadClass(clazz)
|
||||||
|
} catch (e: ClassNotFoundException) {
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw ClassNotFoundException(clazz)
|
||||||
|
}
|
@ -9,8 +9,6 @@ import java.lang.Character.isJavaIdentifierStart
|
|||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any object that implements this interface is expected to expose its own fields via the [get] method, exactly
|
* Any object that implements this interface is expected to expose its own fields via the [get] method, exactly
|
||||||
* as if `this.class.getMethod("get" + name.capitalize()).invoke(this)` had been called. It is intended as a more
|
* as if `this.class.getMethod("get" + name.capitalize()).invoke(this)` had been called. It is intended as a more
|
||||||
@ -20,14 +18,10 @@ interface SimpleFieldAccess {
|
|||||||
operator fun get(name: String): Any?
|
operator fun get(name: String): Any?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
class CarpenterClassLoader : ClassLoader(Thread.currentThread().contextClassLoader) {
|
class CarpenterClassLoader : ClassLoader(Thread.currentThread().contextClassLoader) {
|
||||||
fun load(name: String, bytes: ByteArray) = defineClass(name, bytes, 0, bytes.size)
|
fun load(name: String, bytes: ByteArray) = defineClass(name, bytes, 0, bytes.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class carpenter generates JVM bytecodes for a class given a schema and then loads it into a sub-classloader.
|
* A class carpenter generates JVM bytecodes for a class given a schema and then loads it into a sub-classloader.
|
||||||
* The generated classes have getters, a toString method and implement a simple property access interface. The
|
* The generated classes have getters, a toString method and implement a simple property access interface. The
|
||||||
@ -91,7 +85,8 @@ class ClassCarpenter {
|
|||||||
* Generate bytecode for the given schema and load into the JVM. The returned class object can be used to
|
* Generate bytecode for the given schema and load into the JVM. The returned class object can be used to
|
||||||
* construct instances of the generated class.
|
* construct instances of the generated class.
|
||||||
*
|
*
|
||||||
* @throws DuplicateNameException if the schema's name is already taken in this namespace (you can create a new ClassCarpenter if you're OK with ambiguous names)
|
* @throws DuplicateNameException if the schema's name is already taken in this namespace (you can create a
|
||||||
|
* new ClassCarpenter if you're OK with ambiguous names)
|
||||||
*/
|
*/
|
||||||
fun build(schema: Schema): Class<*> {
|
fun build(schema: Schema): Class<*> {
|
||||||
validateSchema(schema)
|
validateSchema(schema)
|
||||||
@ -257,9 +252,7 @@ class ClassCarpenter {
|
|||||||
visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
|
visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
|
||||||
} else {
|
} else {
|
||||||
var slot = 1
|
var slot = 1
|
||||||
for (fieldType in superclassFields.values)
|
superclassFields.values.forEach { slot += load(slot, it) }
|
||||||
slot += load(slot, fieldType)
|
|
||||||
//val superDesc = schema.superclass.descriptorsIncludingSuperclasses().values.joinToString("")
|
|
||||||
val superDesc = sc.descriptorsIncludingSuperclasses().values.joinToString("")
|
val superDesc = sc.descriptorsIncludingSuperclasses().values.joinToString("")
|
||||||
visitMethodInsn(INVOKESPECIAL, sc.name.jvm, "<init>", "($superDesc)V", false)
|
visitMethodInsn(INVOKESPECIAL, sc.name.jvm, "<init>", "($superDesc)V", false)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package net.corda.core.serialization.carpenter
|
package net.corda.core.serialization.carpenter
|
||||||
|
|
||||||
|
|
||||||
class DuplicateNameException : RuntimeException (
|
class DuplicateNameException : RuntimeException (
|
||||||
"An attempt was made to register two classes with the same name within the same ClassCarpenter namespace.")
|
"An attempt was made to register two classes with the same name within the same ClassCarpenter namespace.")
|
||||||
|
|
||||||
class InterfaceMismatchException(msg: String) : RuntimeException(msg)
|
class InterfaceMismatchException(msg: String) : RuntimeException(msg)
|
||||||
|
|
||||||
class NullablePrimitiveException(msg: String) : RuntimeException(msg)
|
class NullablePrimitiveException(msg: String) : RuntimeException(msg)
|
||||||
|
|
||||||
|
class UncarpentableException (name: String, field: String, type: String) :
|
||||||
|
Exception ("Class $name is loadable yet contains field $field of unknown type $type")
|
||||||
|
@ -3,8 +3,6 @@ package net.corda.core.serialization.carpenter
|
|||||||
import net.corda.core.serialization.amqp.CompositeType
|
import net.corda.core.serialization.amqp.CompositeType
|
||||||
import net.corda.core.serialization.amqp.TypeNotation
|
import net.corda.core.serialization.amqp.TypeNotation
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generated from an AMQP schema this class represents the classes unknown to the deserialiser and that thusly
|
* Generated from an AMQP schema this class represents the classes unknown to the deserialiser and that thusly
|
||||||
* require carpenting up in bytecode form. This is a multi step process as carpenting one object may be depedent
|
* require carpenting up in bytecode form. This is a multi step process as carpenting one object may be depedent
|
||||||
@ -27,8 +25,7 @@ import net.corda.core.serialization.amqp.TypeNotation
|
|||||||
data class CarpenterSchemas (
|
data class CarpenterSchemas (
|
||||||
val carpenterSchemas : MutableList<Schema>,
|
val carpenterSchemas : MutableList<Schema>,
|
||||||
val dependencies : MutableMap<String, Pair<TypeNotation, MutableList<String>>>,
|
val dependencies : MutableMap<String, Pair<TypeNotation, MutableList<String>>>,
|
||||||
val dependsOn : MutableMap<String, MutableList<String>>)
|
val dependsOn : MutableMap<String, MutableList<String>>) {
|
||||||
{
|
|
||||||
companion object CarpenterSchemaConstructor {
|
companion object CarpenterSchemaConstructor {
|
||||||
fun newInstance(): CarpenterSchemas {
|
fun newInstance(): CarpenterSchemas {
|
||||||
return CarpenterSchemas(
|
return CarpenterSchemas(
|
||||||
@ -47,8 +44,6 @@ data class CarpenterSchemas (
|
|||||||
get() = carpenterSchemas.size
|
get() = carpenterSchemas.size
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take a dependency tree of [CarpenterSchemas] and reduce it to zero by carpenting those classes that
|
* Take a dependency tree of [CarpenterSchemas] and reduce it to zero by carpenting those classes that
|
||||||
* require it. As classes are carpented check for depdency resolution, if now free generate a [Schema] for
|
* require it. As classes are carpented check for depdency resolution, if now free generate a [Schema] for
|
||||||
@ -65,15 +60,15 @@ abstract class MetaCarpenterBase (val schemas : CarpenterSchemas) {
|
|||||||
fun step (newObject : Schema) {
|
fun step (newObject : Schema) {
|
||||||
objects[newObject.name] = cc.build (newObject)
|
objects[newObject.name] = cc.build (newObject)
|
||||||
|
|
||||||
/* go over the list of everything that had a dependency on the newly
|
// go over the list of everything that had a dependency on the newly
|
||||||
carpented class existing and remove it from their dependency list, If that
|
// carpented class existing and remove it from their dependency list, If that
|
||||||
list is now empty we have no impediment to carpenting that class up */
|
// list is now empty we have no impediment to carpenting that class up
|
||||||
schemas.dependsOn.remove(newObject.name)?.forEach { dependent ->
|
schemas.dependsOn.remove(newObject.name)?.forEach { dependent ->
|
||||||
assert (newObject.name in schemas.dependencies[dependent]!!.second)
|
assert (newObject.name in schemas.dependencies[dependent]!!.second)
|
||||||
|
|
||||||
schemas.dependencies[dependent]?.second?.remove(newObject.name)
|
schemas.dependencies[dependent]?.second?.remove(newObject.name)
|
||||||
|
|
||||||
/* we're out of blockers so we can now create the type */
|
// we're out of blockers so we can now create the type
|
||||||
if (schemas.dependencies[dependent]?.second?.isEmpty() ?: false) {
|
if (schemas.dependencies[dependent]?.second?.isEmpty() ?: false) {
|
||||||
(schemas.dependencies.remove (dependent)?.first as CompositeType).carpenterSchema (
|
(schemas.dependencies.remove (dependent)?.first as CompositeType).carpenterSchema (
|
||||||
classLoaders = listOf<ClassLoader> (
|
classLoaders = listOf<ClassLoader> (
|
||||||
@ -87,8 +82,6 @@ abstract class MetaCarpenterBase (val schemas : CarpenterSchemas) {
|
|||||||
abstract fun build()
|
abstract fun build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
class MetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
|
class MetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
|
||||||
override fun build() {
|
override fun build() {
|
||||||
while (schemas.carpenterSchemas.isNotEmpty()) {
|
while (schemas.carpenterSchemas.isNotEmpty()) {
|
||||||
@ -98,8 +91,6 @@ class MetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
class TestMetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
|
class TestMetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schemas) {
|
||||||
override fun build() {
|
override fun build() {
|
||||||
if (schemas.carpenterSchemas.isEmpty()) return
|
if (schemas.carpenterSchemas.isEmpty()) return
|
||||||
@ -107,4 +98,3 @@ class TestMetaCarpenter (schemas : CarpenterSchemas) : MetaCarpenterBase (schema
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
@ -264,7 +264,6 @@ class ClassCarpenterTest {
|
|||||||
mapOf("a" to NonNullableField (Int::class.java)))
|
mapOf("a" to NonNullableField (Int::class.java)))
|
||||||
|
|
||||||
val clazz = cc.build(schema)
|
val clazz = cc.build(schema)
|
||||||
|
|
||||||
val a : Int? = null
|
val a : Int? = null
|
||||||
clazz.constructors[0].newInstance(a)
|
clazz.constructors[0].newInstance(a)
|
||||||
}
|
}
|
||||||
@ -364,7 +363,6 @@ class ClassCarpenterTest {
|
|||||||
val clazz = cc.build(schema)
|
val clazz = cc.build(schema)
|
||||||
|
|
||||||
val i = clazz.constructors[0].newInstance(arrayOf(1, 2, 3)) as SimpleFieldAccess
|
val i = clazz.constructors[0].newInstance(arrayOf(1, 2, 3)) as SimpleFieldAccess
|
||||||
|
|
||||||
val arr = clazz.getMethod("getA").invoke(i)
|
val arr = clazz.getMethod("getA").invoke(i)
|
||||||
|
|
||||||
assertEquals(1, (arr as Array<Int>)[0])
|
assertEquals(1, (arr as Array<Int>)[0])
|
||||||
@ -384,14 +382,12 @@ class ClassCarpenterTest {
|
|||||||
"c" to Int::class.java).mapValues { NonNullableField(it.value) })
|
"c" to Int::class.java).mapValues { NonNullableField(it.value) })
|
||||||
|
|
||||||
val clazz = cc.build(schema)
|
val clazz = cc.build(schema)
|
||||||
|
|
||||||
val i = clazz.constructors[0].newInstance(2, intArrayOf(4, 8), 16) as SimpleFieldAccess
|
val i = clazz.constructors[0].newInstance(2, intArrayOf(4, 8), 16) as SimpleFieldAccess
|
||||||
|
|
||||||
assertEquals(2, clazz.getMethod("getA").invoke(i))
|
assertEquals(2, clazz.getMethod("getA").invoke(i))
|
||||||
assertEquals(4, (clazz.getMethod("getB").invoke(i) as IntArray)[0])
|
assertEquals(4, (clazz.getMethod("getB").invoke(i) as IntArray)[0])
|
||||||
assertEquals(8, (clazz.getMethod("getB").invoke(i) as IntArray)[1])
|
assertEquals(8, (clazz.getMethod("getB").invoke(i) as IntArray)[1])
|
||||||
assertEquals(16, clazz.getMethod("getC").invoke(i))
|
assertEquals(16, clazz.getMethod("getC").invoke(i))
|
||||||
|
|
||||||
assertEquals("$className{a=2, b=[4, 8], c=16}", i.toString())
|
assertEquals("$className{a=2, b=[4, 8], c=16}", i.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +410,6 @@ class ClassCarpenterTest {
|
|||||||
assertEquals(4, (clazz.getMethod("getC").invoke(i) as IntArray)[0])
|
assertEquals(4, (clazz.getMethod("getC").invoke(i) as IntArray)[0])
|
||||||
assertEquals(5, (clazz.getMethod("getC").invoke(i) as IntArray)[1])
|
assertEquals(5, (clazz.getMethod("getC").invoke(i) as IntArray)[1])
|
||||||
assertEquals(6, (clazz.getMethod("getC").invoke(i) as IntArray)[2])
|
assertEquals(6, (clazz.getMethod("getC").invoke(i) as IntArray)[2])
|
||||||
|
|
||||||
assertEquals("$className{a=[1, 2], b=3, c=[4, 5, 6]}", i.toString())
|
assertEquals("$className{a=[1, 2], b=3, c=[4, 5, 6]}", i.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +449,6 @@ class ClassCarpenterTest {
|
|||||||
"and on the side",
|
"and on the side",
|
||||||
arrayOf("some pickles", "some fries"))
|
arrayOf("some pickles", "some fries"))
|
||||||
|
|
||||||
|
|
||||||
val arr1 = clazz.getMethod("getA").invoke(i) as Array<String>
|
val arr1 = clazz.getMethod("getA").invoke(i) as Array<String>
|
||||||
val arr2 = clazz.getMethod("getC").invoke(i) as Array<String>
|
val arr2 = clazz.getMethod("getC").invoke(i) as Array<String>
|
||||||
|
|
||||||
@ -477,16 +471,12 @@ class ClassCarpenterTest {
|
|||||||
val clazz = cc.build(schema)
|
val clazz = cc.build(schema)
|
||||||
|
|
||||||
assertEquals (2, clazz.declaredFields.size)
|
assertEquals (2, clazz.declaredFields.size)
|
||||||
|
|
||||||
assertEquals (1, clazz.getDeclaredField("a").annotations.size)
|
assertEquals (1, clazz.getDeclaredField("a").annotations.size)
|
||||||
assertEquals (javax.annotation.Nullable::class.java, clazz.getDeclaredField("a").annotations[0].annotationClass.java)
|
assertEquals (javax.annotation.Nullable::class.java, clazz.getDeclaredField("a").annotations[0].annotationClass.java)
|
||||||
|
|
||||||
assertEquals (1, clazz.getDeclaredField("b").annotations.size)
|
assertEquals (1, clazz.getDeclaredField("b").annotations.size)
|
||||||
assertEquals (javax.annotation.Nonnull::class.java, clazz.getDeclaredField("b").annotations[0].annotationClass.java)
|
assertEquals (javax.annotation.Nonnull::class.java, clazz.getDeclaredField("b").annotations[0].annotationClass.java)
|
||||||
|
|
||||||
assertEquals (1, clazz.getMethod("getA").annotations.size)
|
assertEquals (1, clazz.getMethod("getA").annotations.size)
|
||||||
assertEquals (javax.annotation.Nullable::class.java, clazz.getMethod("getA").annotations[0].annotationClass.java)
|
assertEquals (javax.annotation.Nullable::class.java, clazz.getMethod("getA").annotations[0].annotationClass.java)
|
||||||
|
|
||||||
assertEquals (1, clazz.getMethod("getB").annotations.size)
|
assertEquals (1, clazz.getMethod("getB").annotations.size)
|
||||||
assertEquals (javax.annotation.Nonnull::class.java, clazz.getMethod("getB").annotations[0].annotationClass.java)
|
assertEquals (javax.annotation.Nonnull::class.java, clazz.getMethod("getB").annotations[0].annotationClass.java)
|
||||||
}
|
}
|
||||||
@ -503,5 +493,4 @@ class ClassCarpenterTest {
|
|||||||
assertNotEquals(null, descriptors.find { it.name == "a" })
|
assertNotEquals(null, descriptors.find { it.name == "a" })
|
||||||
assertNotEquals(null, descriptors.find { it.name == "class" })
|
assertNotEquals(null, descriptors.find { it.name == "class" })
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,32 +7,25 @@ import net.corda.core.serialization.amqp.TypeNotation
|
|||||||
import net.corda.core.serialization.amqp.SerializerFactory
|
import net.corda.core.serialization.amqp.SerializerFactory
|
||||||
import net.corda.core.serialization.amqp.SerializationOutput
|
import net.corda.core.serialization.amqp.SerializationOutput
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
fun mangleName(name: String) = "${name}__carpenter"
|
||||||
|
|
||||||
fun corruptName(name: String) = "${name}__carpenter"
|
/**
|
||||||
|
* given a list of class names work through the amqp envelope schema and alter any that
|
||||||
/**********************************************************************************************************************/
|
* match in the fashion defined above
|
||||||
|
*/
|
||||||
/* given a list of class names work through the amqp envelope schema and alter any that
|
fun Schema.mangleName(names: List<String>): Schema {
|
||||||
match in the fashion defined above */
|
|
||||||
fun Schema.corruptName(names: List<String>): Schema {
|
|
||||||
val newTypes: MutableList<TypeNotation> = mutableListOf()
|
val newTypes: MutableList<TypeNotation> = mutableListOf()
|
||||||
|
|
||||||
for (type in types) {
|
for (type in types) {
|
||||||
val newName = if (type.name in names) corruptName(type.name) else type.name
|
val newName = if (type.name in names) mangleName(type.name) else type.name
|
||||||
|
val newProvides = type.provides.map { it -> if (it in names) mangleName(it) else it }
|
||||||
val newProvides = type.provides.map {
|
|
||||||
it ->
|
|
||||||
if (it in names) corruptName(it) else it
|
|
||||||
}
|
|
||||||
|
|
||||||
val newFields = mutableListOf<Field>()
|
val newFields = mutableListOf<Field>()
|
||||||
|
|
||||||
(type as CompositeType).fields.forEach {
|
(type as CompositeType).fields.forEach {
|
||||||
val fieldType = if (it.type in names) corruptName(it.type) else it.type
|
val fieldType = if (it.type in names) mangleName(it.type) else it.type
|
||||||
|
val requires =
|
||||||
val requires = if (it.requires.isNotEmpty() && (it.requires[0] in names))
|
if (it.requires.isNotEmpty() && (it.requires[0] in names)) listOf(mangleName(it.requires[0]))
|
||||||
listOf(corruptName(it.requires[0])) else it.requires
|
else it.requires
|
||||||
|
|
||||||
newFields.add(it.copy(type = fieldType, requires = requires))
|
newFields.add(it.copy(type = fieldType, requires = requires))
|
||||||
}
|
}
|
||||||
@ -43,8 +36,6 @@ fun Schema.corruptName(names: List<String>): Schema {
|
|||||||
return Schema(types = newTypes)
|
return Schema(types = newTypes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************/
|
|
||||||
|
|
||||||
open class AmqpCarpenterBase {
|
open class AmqpCarpenterBase {
|
||||||
var factory = SerializerFactory()
|
var factory = SerializerFactory()
|
||||||
|
|
||||||
|
@ -14,11 +14,7 @@ interface I_ {
|
|||||||
val a: Int
|
val a: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Where a class has a member that is also a composite type or interface
|
|
||||||
*/
|
|
||||||
class CompositeMembers : AmqpCarpenterBase() {
|
class CompositeMembers : AmqpCarpenterBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun bothKnown() {
|
fun bothKnown() {
|
||||||
val testA = 10
|
val testA = 10
|
||||||
@ -31,7 +27,6 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
data class B(val a: A, var b: Int)
|
data class B(val a: A, var b: Int)
|
||||||
|
|
||||||
val b = B(A(testA), testB)
|
val b = B(A(testA), testB)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||||
|
|
||||||
assert(obj.obj is B)
|
assert(obj.obj is B)
|
||||||
@ -57,10 +52,8 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
assert(amqpSchemaA != null)
|
assert(amqpSchemaA != null)
|
||||||
assert(amqpSchemaB != null)
|
assert(amqpSchemaB != null)
|
||||||
|
|
||||||
/*
|
// Just ensure the amqp schema matches what we want before we go messing
|
||||||
* Just ensure the amqp schema matches what we want before we go messing
|
// around with the internals
|
||||||
* around with the internals
|
|
||||||
*/
|
|
||||||
assertEquals(1, amqpSchemaA?.fields?.size)
|
assertEquals(1, amqpSchemaA?.fields?.size)
|
||||||
assertEquals("a", amqpSchemaA!!.fields[0].name)
|
assertEquals("a", amqpSchemaA!!.fields[0].name)
|
||||||
assertEquals("int", amqpSchemaA.fields[0].type)
|
assertEquals("int", amqpSchemaA.fields[0].type)
|
||||||
@ -73,15 +66,15 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
val metaSchema = obj.envelope.schema.carpenterSchema()
|
val metaSchema = obj.envelope.schema.carpenterSchema()
|
||||||
|
|
||||||
/* if we know all the classes there is nothing to really achieve here */
|
// if we know all the classes there is nothing to really achieve here
|
||||||
assert(metaSchema.carpenterSchemas.isEmpty())
|
assert(metaSchema.carpenterSchemas.isEmpty())
|
||||||
assert(metaSchema.dependsOn.isEmpty())
|
assert(metaSchema.dependsOn.isEmpty())
|
||||||
assert(metaSchema.dependencies.isEmpty())
|
assert(metaSchema.dependencies.isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
/* you cannot have an element of a composite class we know about
|
// you cannot have an element of a composite class we know about
|
||||||
that is unknown as that should be impossible. If we have the containing
|
// that is unknown as that should be impossible. If we have the containing
|
||||||
class in the class path then we must have all of it's constituent elements */
|
// class in the class path then we must have all of it's constituent elements
|
||||||
@Test(expected = UncarpentableException::class)
|
@Test(expected = UncarpentableException::class)
|
||||||
fun nestedIsUnknown() {
|
fun nestedIsUnknown() {
|
||||||
val testA = 10
|
val testA = 10
|
||||||
@ -96,7 +89,7 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
val b = B(A(testA), testB)
|
val b = B(A(testA), testB)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||||
val amqpSchema = obj.envelope.schema.corruptName(listOf (classTestName ("A")))
|
val amqpSchema = obj.envelope.schema.mangleName(listOf (classTestName ("A")))
|
||||||
|
|
||||||
assert(obj.obj is B)
|
assert(obj.obj is B)
|
||||||
|
|
||||||
@ -115,13 +108,11 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
data class B(val a: A, var b: Int)
|
data class B(val a: A, var b: Int)
|
||||||
|
|
||||||
val b = B(A(testA), testB)
|
val b = B(A(testA), testB)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||||
|
|
||||||
assert(obj.obj is B)
|
assert(obj.obj is B)
|
||||||
|
|
||||||
val amqpSchema = obj.envelope.schema.corruptName(listOf(classTestName("B")))
|
val amqpSchema = obj.envelope.schema.mangleName(listOf(classTestName("B")))
|
||||||
|
|
||||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||||
|
|
||||||
assertEquals(1, carpenterSchema.size)
|
assertEquals(1, carpenterSchema.size)
|
||||||
@ -130,11 +121,11 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
metaCarpenter.build()
|
metaCarpenter.build()
|
||||||
|
|
||||||
assert(corruptName(classTestName("B")) in metaCarpenter.objects)
|
assert(mangleName(classTestName("B")) in metaCarpenter.objects)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun BothUnkown() {
|
fun BothUnknown() {
|
||||||
val testA = 10
|
val testA = 10
|
||||||
val testB = 20
|
val testB = 20
|
||||||
|
|
||||||
@ -145,52 +136,50 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
data class B(val a: A, var b: Int)
|
data class B(val a: A, var b: Int)
|
||||||
|
|
||||||
val b = B(A(testA), testB)
|
val b = B(A(testA), testB)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||||
|
|
||||||
assert(obj.obj is B)
|
assert(obj.obj is B)
|
||||||
|
|
||||||
val amqpSchema = obj.envelope.schema.corruptName(listOf(classTestName("A"), classTestName("B")))
|
val amqpSchema = obj.envelope.schema.mangleName(listOf(classTestName("A"), classTestName("B")))
|
||||||
|
|
||||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||||
|
|
||||||
/* just verify we're in the expected initial state, A is carpentable, B is not because
|
// just verify we're in the expected initial state, A is carpentable, B is not because
|
||||||
it depends on A and the dependency chains are in place */
|
// it depends on A and the dependency chains are in place
|
||||||
assertEquals(1, carpenterSchema.size)
|
assertEquals(1, carpenterSchema.size)
|
||||||
assertEquals(corruptName(classTestName("A")), carpenterSchema.carpenterSchemas.first().name)
|
assertEquals(mangleName(classTestName("A")), carpenterSchema.carpenterSchemas.first().name)
|
||||||
assertEquals(1, carpenterSchema.dependencies.size)
|
assertEquals(1, carpenterSchema.dependencies.size)
|
||||||
assert(corruptName(classTestName("B")) in carpenterSchema.dependencies)
|
assert(mangleName(classTestName("B")) in carpenterSchema.dependencies)
|
||||||
assertEquals(1, carpenterSchema.dependsOn.size)
|
assertEquals(1, carpenterSchema.dependsOn.size)
|
||||||
assert(corruptName(classTestName("A")) in carpenterSchema.dependsOn)
|
assert(mangleName(classTestName("A")) in carpenterSchema.dependsOn)
|
||||||
|
|
||||||
/* test meta carpenter lets us single step over the creation */
|
|
||||||
val metaCarpenter = TestMetaCarpenter(carpenterSchema)
|
val metaCarpenter = TestMetaCarpenter(carpenterSchema)
|
||||||
|
|
||||||
/* we've built nothing so nothing should be there */
|
|
||||||
assertEquals(0, metaCarpenter.objects.size)
|
assertEquals(0, metaCarpenter.objects.size)
|
||||||
|
|
||||||
/* first iteration, carpent A, resolve deps and mark B as carpentable */
|
// first iteration, carpent A, resolve deps and mark B as carpentable
|
||||||
metaCarpenter.build()
|
metaCarpenter.build()
|
||||||
|
|
||||||
/* one build iteration should have carpetned up A and worked out that B is now buildable
|
// one build iteration should have carpetned up A and worked out that B is now buildable
|
||||||
given it's depedencies have been satisfied */
|
// given it's depedencies have been satisfied
|
||||||
assertTrue(corruptName(classTestName("A")) in metaCarpenter.objects)
|
assertTrue(mangleName(classTestName("A")) in metaCarpenter.objects)
|
||||||
assertFalse(corruptName(classTestName("B")) in metaCarpenter.objects)
|
assertFalse(mangleName(classTestName("B")) in metaCarpenter.objects)
|
||||||
|
|
||||||
assertEquals(1, carpenterSchema.carpenterSchemas.size)
|
assertEquals(1, carpenterSchema.carpenterSchemas.size)
|
||||||
assertEquals(corruptName(classTestName("B")), carpenterSchema.carpenterSchemas.first().name)
|
assertEquals(mangleName(classTestName("B")), carpenterSchema.carpenterSchemas.first().name)
|
||||||
assertTrue(carpenterSchema.dependencies.isEmpty())
|
assertTrue(carpenterSchema.dependencies.isEmpty())
|
||||||
assertTrue(carpenterSchema.dependsOn.isEmpty())
|
assertTrue(carpenterSchema.dependsOn.isEmpty())
|
||||||
|
|
||||||
/* second manual iteration, will carpent B */
|
// second manual iteration, will carpent B
|
||||||
metaCarpenter.build()
|
metaCarpenter.build()
|
||||||
assert(corruptName(classTestName("A")) in metaCarpenter.objects)
|
assert(mangleName(classTestName("A")) in metaCarpenter.objects)
|
||||||
assert(corruptName(classTestName("B")) in metaCarpenter.objects)
|
assert(mangleName(classTestName("B")) in metaCarpenter.objects)
|
||||||
|
|
||||||
|
// and we must be finished
|
||||||
assertTrue(carpenterSchema.carpenterSchemas.isEmpty())
|
assertTrue(carpenterSchema.carpenterSchemas.isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UncarpentableException::class)
|
@Test(expected = UncarpentableException::class)
|
||||||
|
@Suppress("UNUSED")
|
||||||
fun nestedIsUnkownInherited() {
|
fun nestedIsUnkownInherited() {
|
||||||
val testA = 10
|
val testA = 10
|
||||||
val testB = 20
|
val testB = 20
|
||||||
@ -206,18 +195,18 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
data class C(val b: B, var c: Int)
|
data class C(val b: B, var c: Int)
|
||||||
|
|
||||||
val c = C(B(testA, testB), testC)
|
val c = C(B(testA, testB), testC)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(c))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(c))
|
||||||
|
|
||||||
assert(obj.obj is C)
|
assert(obj.obj is C)
|
||||||
|
|
||||||
val amqpSchema = obj.envelope.schema.corruptName(listOf(classTestName("A"), classTestName("B")))
|
val amqpSchema = obj.envelope.schema.mangleName(listOf(classTestName("A"), classTestName("B")))
|
||||||
|
|
||||||
amqpSchema.carpenterSchema()
|
amqpSchema.carpenterSchema()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = UncarpentableException::class)
|
@Test(expected = UncarpentableException::class)
|
||||||
fun nestedIsUnknownInheritedUnkown() {
|
@Suppress("UNUSED")
|
||||||
|
fun nestedIsUnknownInheritedUnknown() {
|
||||||
val testA = 10
|
val testA = 10
|
||||||
val testB = 20
|
val testB = 20
|
||||||
val testC = 30
|
val testC = 30
|
||||||
@ -232,16 +221,16 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
data class C(val b: B, var c: Int)
|
data class C(val b: B, var c: Int)
|
||||||
|
|
||||||
val c = C(B(testA, testB), testC)
|
val c = C(B(testA, testB), testC)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(c))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(c))
|
||||||
|
|
||||||
assert(obj.obj is C)
|
assert(obj.obj is C)
|
||||||
|
|
||||||
val amqpSchema = obj.envelope.schema.corruptName(listOf(classTestName("A"), classTestName("B")))
|
val amqpSchema = obj.envelope.schema.mangleName(listOf(classTestName("A"), classTestName("B")))
|
||||||
|
|
||||||
amqpSchema.carpenterSchema()
|
amqpSchema.carpenterSchema()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNUSED")
|
||||||
@Test(expected = UncarpentableException::class)
|
@Test(expected = UncarpentableException::class)
|
||||||
fun parentsIsUnknownWithUnknownInheritedMember() {
|
fun parentsIsUnknownWithUnknownInheritedMember() {
|
||||||
val testA = 10
|
val testA = 10
|
||||||
@ -258,18 +247,14 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
data class C(val b: B, var c: Int)
|
data class C(val b: B, var c: Int)
|
||||||
|
|
||||||
val c = C(B(testA, testB), testC)
|
val c = C(B(testA, testB), testC)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(c))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(c))
|
||||||
|
|
||||||
assert(obj.obj is C)
|
assert(obj.obj is C)
|
||||||
|
|
||||||
val carpenterSchema = obj.envelope.schema.corruptName(listOf(classTestName("A"), classTestName("B")))
|
val carpenterSchema = obj.envelope.schema.mangleName(listOf(classTestName("A"), classTestName("B")))
|
||||||
|
|
||||||
TestMetaCarpenter(carpenterSchema.carpenterSchema())
|
TestMetaCarpenter(carpenterSchema.carpenterSchema())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO serializer doesn't support inheritnace at the moment, when it does this should work
|
* TODO serializer doesn't support inheritnace at the moment, when it does this should work
|
||||||
@Test
|
@Test
|
||||||
@ -284,19 +269,17 @@ class CompositeMembers : AmqpCarpenterBase() {
|
|||||||
class B(override val a: Int, val b: Int) : A (a)
|
class B(override val a: Int, val b: Int) : A (a)
|
||||||
|
|
||||||
val b = B(testA, testB)
|
val b = B(testA, testB)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||||
|
|
||||||
assert(obj.obj is B)
|
assert(obj.obj is B)
|
||||||
|
|
||||||
val carpenterSchema = obj.envelope.schema.corruptName(listOf(classTestName("A"), classTestName("B")))
|
val carpenterSchema = obj.envelope.schema.mangleName(listOf(classTestName("A"), classTestName("B")))
|
||||||
|
|
||||||
val metaCarpenter = TestMetaCarpenter(carpenterSchema.carpenterSchema())
|
val metaCarpenter = TestMetaCarpenter(carpenterSchema.carpenterSchema())
|
||||||
|
|
||||||
assertEquals(1, metaCarpenter.schemas.carpenterSchemas.size)
|
assertEquals(1, metaCarpenter.schemas.carpenterSchemas.size)
|
||||||
assertEquals(corruptName(classTestName("B")), metaCarpenter.schemas.carpenterSchemas.first().name)
|
assertEquals(mangleName(classTestName("B")), metaCarpenter.schemas.carpenterSchemas.first().name)
|
||||||
assertEquals(1, metaCarpenter.schemas.dependencies.size)
|
assertEquals(1, metaCarpenter.schemas.dependencies.size)
|
||||||
assertTrue(corruptName(classTestName("A")) in metaCarpenter.schemas.dependencies)
|
assertTrue(mangleName(classTestName("A")) in metaCarpenter.schemas.dependencies)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,11 @@ import net.corda.core.serialization.amqp.*
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
/*******************************************************************************************************/
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
interface J {
|
interface J {
|
||||||
val j: Int
|
val j: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************************************/
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
interface I {
|
interface I {
|
||||||
val i: Int
|
val i: Int
|
||||||
@ -39,49 +35,36 @@ interface IIII {
|
|||||||
val i: I
|
val i: I
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************************************/
|
|
||||||
|
|
||||||
class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun interfaceParent1() {
|
fun interfaceParent1() {
|
||||||
val testJ = 20
|
|
||||||
|
|
||||||
class A(override val j: Int) : J
|
class A(override val j: Int) : J
|
||||||
|
|
||||||
|
val testJ = 20
|
||||||
val a = A(testJ)
|
val a = A(testJ)
|
||||||
|
|
||||||
assertEquals(testJ, a.j)
|
assertEquals(testJ, a.j)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
|
|
||||||
val serSchema = obj.envelope.schema
|
val serSchema = obj.envelope.schema
|
||||||
|
|
||||||
assertEquals(2, serSchema.types.size)
|
assertEquals(2, serSchema.types.size)
|
||||||
|
|
||||||
val l1 = serSchema.carpenterSchema()
|
val l1 = serSchema.carpenterSchema()
|
||||||
|
|
||||||
/* since we're using an envelope generated by seilaising classes defined locally
|
// since we're using an envelope generated by seilaising classes defined locally
|
||||||
it's extremely unlikely we'd need to carpent any classes */
|
// it's extremely unlikely we'd need to carpent any classes
|
||||||
assertEquals(0, l1.size)
|
assertEquals(0, l1.size)
|
||||||
|
|
||||||
val corruptSchema = serSchema.corruptName(listOf(classTestName("A")))
|
val mangleSchema = serSchema.mangleName(listOf(classTestName("A")))
|
||||||
|
val l2 = mangleSchema.carpenterSchema()
|
||||||
val l2 = corruptSchema.carpenterSchema()
|
|
||||||
|
|
||||||
assertEquals(1, l2.size)
|
assertEquals(1, l2.size)
|
||||||
val aSchema = l2.carpenterSchemas.find { it.name == corruptName(classTestName("A")) }
|
|
||||||
|
|
||||||
|
val aSchema = l2.carpenterSchemas.find { it.name == mangleName(classTestName("A")) }
|
||||||
assertNotEquals(null, aSchema)
|
assertNotEquals(null, aSchema)
|
||||||
|
assertEquals(mangleName(classTestName("A")), aSchema!!.name)
|
||||||
assertEquals(corruptName(classTestName("A")), aSchema!!.name)
|
|
||||||
assertEquals(1, aSchema.interfaces.size)
|
assertEquals(1, aSchema.interfaces.size)
|
||||||
assertEquals(net.corda.core.serialization.carpenter.J::class.java, aSchema.interfaces[0])
|
assertEquals(net.corda.core.serialization.carpenter.J::class.java, aSchema.interfaces[0])
|
||||||
|
|
||||||
val aBuilder = ClassCarpenter().build(aSchema)
|
val aBuilder = ClassCarpenter().build(aSchema)
|
||||||
|
|
||||||
val objJ = aBuilder.constructors[0].newInstance(testJ)
|
val objJ = aBuilder.constructors[0].newInstance(testJ)
|
||||||
val j = objJ as J
|
val j = objJ as J
|
||||||
|
|
||||||
@ -89,14 +72,12 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
assertEquals(a.j, j.j)
|
assertEquals(a.j, j.j)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun interfaceParent2() {
|
fun interfaceParent2() {
|
||||||
val testJ = 20
|
|
||||||
val testJJ = 40
|
|
||||||
|
|
||||||
class A(override val j: Int, val jj: Int) : J
|
class A(override val j: Int, val jj: Int) : J
|
||||||
|
|
||||||
|
val testJ = 20
|
||||||
|
val testJJ = 40
|
||||||
val a = A(testJ, testJJ)
|
val a = A(testJ, testJJ)
|
||||||
|
|
||||||
assertEquals(testJ, a.j)
|
assertEquals(testJ, a.j)
|
||||||
@ -112,14 +93,12 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
val l1 = serSchema.carpenterSchema()
|
val l1 = serSchema.carpenterSchema()
|
||||||
|
|
||||||
/* since we're using an envelope generated by seilaising classes defined locally
|
|
||||||
it's extremely unlikely we'd need to carpent any classes */
|
|
||||||
assertEquals(0, l1.size)
|
assertEquals(0, l1.size)
|
||||||
|
|
||||||
val corruptSchema = serSchema.corruptName(listOf(classTestName("A")))
|
val mangleSchema = serSchema.mangleName(listOf(classTestName("A")))
|
||||||
val aName = corruptName(classTestName("A"))
|
val aName = mangleName(classTestName("A"))
|
||||||
|
|
||||||
val l2 = corruptSchema.carpenterSchema()
|
val l2 = mangleSchema.carpenterSchema()
|
||||||
|
|
||||||
assertEquals(1, l2.size)
|
assertEquals(1, l2.size)
|
||||||
|
|
||||||
@ -160,48 +139,43 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
val l1 = serSchema.carpenterSchema()
|
val l1 = serSchema.carpenterSchema()
|
||||||
|
|
||||||
/* since we're using an envelope generated by seilaising classes defined locally
|
// since we're using an envelope generated by serialising classes defined locally
|
||||||
it's extremely unlikely we'd need to carpent any classes */
|
// it's extremely unlikely we'd need to carpent any classes
|
||||||
assertEquals(0, l1.size)
|
assertEquals(0, l1.size)
|
||||||
|
|
||||||
/* pretend we don't know the class we've been sent, i.e. it's unknown to the class loader, and thus
|
// pretend we don't know the class we've been sent, i.e. it's unknown to the class loader, and thus
|
||||||
needs some carpentry */
|
// needs some carpentry
|
||||||
|
val mangleSchema = serSchema.mangleName(listOf(classTestName("A")))
|
||||||
val corruptSchema = serSchema.corruptName(listOf(classTestName("A")))
|
val l2 = mangleSchema.carpenterSchema()
|
||||||
val l2 = corruptSchema.carpenterSchema()
|
val aName = mangleName(classTestName("A"))
|
||||||
val aName = corruptName(classTestName("A"))
|
|
||||||
|
|
||||||
assertEquals(1, l2.size)
|
assertEquals(1, l2.size)
|
||||||
|
|
||||||
val aSchema = l2.carpenterSchemas.find { it.name == aName }
|
val aSchema = l2.carpenterSchemas.find { it.name == aName }
|
||||||
|
|
||||||
assertNotEquals(null, aSchema)
|
assertNotEquals(null, aSchema)
|
||||||
|
|
||||||
assertEquals(aName, aSchema!!.name)
|
assertEquals(aName, aSchema!!.name)
|
||||||
assertEquals(2, aSchema.interfaces.size)
|
assertEquals(2, aSchema.interfaces.size)
|
||||||
assert(net.corda.core.serialization.carpenter.I::class.java in aSchema.interfaces)
|
assert(net.corda.core.serialization.carpenter.I::class.java in aSchema.interfaces)
|
||||||
assert(net.corda.core.serialization.carpenter.II::class.java in aSchema.interfaces)
|
assert(net.corda.core.serialization.carpenter.II::class.java in aSchema.interfaces)
|
||||||
|
|
||||||
val aBuilder = ClassCarpenter().build(aSchema)
|
val aBuilder = ClassCarpenter().build(aSchema)
|
||||||
|
|
||||||
val objA = aBuilder.constructors[0].newInstance(testI, testII)
|
val objA = aBuilder.constructors[0].newInstance(testI, testII)
|
||||||
val i = objA as I
|
val i = objA as I
|
||||||
val ii = objA as II
|
val ii = objA as II
|
||||||
|
|
||||||
assertEquals(aBuilder.getMethod("getI").invoke(objA), testI)
|
assertEquals(aBuilder.getMethod("getI").invoke(objA), testI)
|
||||||
assertEquals(aBuilder.getMethod("getIi").invoke(objA), testII)
|
assertEquals(aBuilder.getMethod("getIi").invoke(objA), testII)
|
||||||
|
|
||||||
assertEquals(a.i, i.i)
|
assertEquals(a.i, i.i)
|
||||||
assertEquals(a.ii, ii.ii)
|
assertEquals(a.ii, ii.ii)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun nestedInterfaces() {
|
fun nestedInterfaces() {
|
||||||
val testI = 20
|
|
||||||
val testIII = 60
|
|
||||||
|
|
||||||
class A(override val i: Int, override val iii: Int) : III
|
class A(override val i: Int, override val iii: Int) : III
|
||||||
|
|
||||||
|
val testI = 20
|
||||||
|
val testIII = 60
|
||||||
val a = A(testI, testIII)
|
val a = A(testI, testIII)
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
@ -213,34 +187,31 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
val l1 = serSchema.carpenterSchema()
|
val l1 = serSchema.carpenterSchema()
|
||||||
|
|
||||||
/* since we're using an envelope generated by seilaising classes defined locally
|
// since we're using an envelope generated by serialising classes defined locally
|
||||||
it's extremely unlikely we'd need to carpent any classes */
|
// it's extremely unlikely we'd need to carpent any classes
|
||||||
assertEquals(0, l1.size)
|
assertEquals(0, l1.size)
|
||||||
|
|
||||||
val corruptSchema = serSchema.corruptName(listOf(classTestName("A")))
|
val mangleSchema = serSchema.mangleName(listOf(classTestName("A")))
|
||||||
val l2 = corruptSchema.carpenterSchema()
|
val l2 = mangleSchema.carpenterSchema()
|
||||||
val aName = corruptName(classTestName("A"))
|
val aName = mangleName(classTestName("A"))
|
||||||
|
|
||||||
assertEquals(1, l2.size)
|
assertEquals(1, l2.size)
|
||||||
|
|
||||||
val aSchema = l2.carpenterSchemas.find { it.name == aName }
|
val aSchema = l2.carpenterSchemas.find { it.name == aName }
|
||||||
|
|
||||||
assertNotEquals(null, aSchema)
|
assertNotEquals(null, aSchema)
|
||||||
|
|
||||||
assertEquals(aName, aSchema!!.name)
|
assertEquals(aName, aSchema!!.name)
|
||||||
assertEquals(2, aSchema.interfaces.size)
|
assertEquals(2, aSchema.interfaces.size)
|
||||||
assert(net.corda.core.serialization.carpenter.I::class.java in aSchema.interfaces)
|
assert(net.corda.core.serialization.carpenter.I::class.java in aSchema.interfaces)
|
||||||
assert(net.corda.core.serialization.carpenter.III::class.java in aSchema.interfaces)
|
assert(net.corda.core.serialization.carpenter.III::class.java in aSchema.interfaces)
|
||||||
|
|
||||||
val aBuilder = ClassCarpenter().build(aSchema)
|
val aBuilder = ClassCarpenter().build(aSchema)
|
||||||
|
|
||||||
val objA = aBuilder.constructors[0].newInstance(testI, testIII)
|
val objA = aBuilder.constructors[0].newInstance(testI, testIII)
|
||||||
val i = objA as I
|
val i = objA as I
|
||||||
val iii = objA as III
|
val iii = objA as III
|
||||||
|
|
||||||
assertEquals(aBuilder.getMethod("getI").invoke(objA), testI)
|
assertEquals(aBuilder.getMethod("getI").invoke(objA), testI)
|
||||||
assertEquals(aBuilder.getMethod("getIii").invoke(objA), testIII)
|
assertEquals(aBuilder.getMethod("getIii").invoke(objA), testIII)
|
||||||
|
|
||||||
assertEquals(a.i, i.i)
|
assertEquals(a.i, i.i)
|
||||||
assertEquals(a.i, iii.i)
|
assertEquals(a.i, iii.i)
|
||||||
assertEquals(a.iii, iii.iii)
|
assertEquals(a.iii, iii.iii)
|
||||||
@ -248,33 +219,30 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun memberInterface() {
|
fun memberInterface() {
|
||||||
val testI = 25
|
|
||||||
val testIIII = 50
|
|
||||||
|
|
||||||
class A(override val i: Int) : I
|
class A(override val i: Int) : I
|
||||||
class B(override val i: I, override val iiii: Int) : IIII
|
class B(override val i: I, override val iiii: Int) : IIII
|
||||||
|
|
||||||
|
val testI = 25
|
||||||
|
val testIIII = 50
|
||||||
val a = A(testI)
|
val a = A(testI)
|
||||||
val b = B(a, testIIII)
|
val b = B(a, testIIII)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||||
|
|
||||||
assert(obj.obj is B)
|
assert(obj.obj is B)
|
||||||
|
|
||||||
val serSchema = obj.envelope.schema
|
val serSchema = obj.envelope.schema
|
||||||
|
|
||||||
/*
|
// Expected classes are
|
||||||
* class A
|
// * class A
|
||||||
* class A's interface (class I)
|
// * class A's interface (class I)
|
||||||
* class B
|
// * class B
|
||||||
* class B's interface (class IIII)
|
// * class B's interface (class IIII)
|
||||||
*/
|
|
||||||
assertEquals(4, serSchema.types.size)
|
assertEquals(4, serSchema.types.size)
|
||||||
|
|
||||||
val corruptSchema = serSchema.corruptName(listOf(classTestName("A"), classTestName("B")))
|
val mangleSchema = serSchema.mangleName(listOf(classTestName("A"), classTestName("B")))
|
||||||
val cSchema = corruptSchema.carpenterSchema()
|
val cSchema = mangleSchema.carpenterSchema()
|
||||||
val aName = corruptName(classTestName("A"))
|
val aName = mangleName(classTestName("A"))
|
||||||
val bName = corruptName(classTestName("B"))
|
val bName = mangleName(classTestName("B"))
|
||||||
|
|
||||||
assertEquals(2, cSchema.size)
|
assertEquals(2, cSchema.size)
|
||||||
|
|
||||||
@ -286,102 +254,90 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
val cc = ClassCarpenter()
|
val cc = ClassCarpenter()
|
||||||
val cc2 = ClassCarpenter()
|
val cc2 = ClassCarpenter()
|
||||||
|
|
||||||
val bBuilder = cc.build(bCarpenterSchema!!)
|
val bBuilder = cc.build(bCarpenterSchema!!)
|
||||||
bBuilder.constructors[0].newInstance(a, testIIII)
|
bBuilder.constructors[0].newInstance(a, testIIII)
|
||||||
|
|
||||||
val aBuilder = cc.build(aCarpenterSchema!!)
|
val aBuilder = cc.build(aCarpenterSchema!!)
|
||||||
val objA = aBuilder.constructors[0].newInstance(testI)
|
val objA = aBuilder.constructors[0].newInstance(testI)
|
||||||
|
|
||||||
/* build a second B this time using our constructed instane of A and not the
|
// build a second B this time using our constructed instance of A and not the
|
||||||
local one we pre defined */
|
// local one we pre defined
|
||||||
bBuilder.constructors[0].newInstance(objA, testIIII)
|
bBuilder.constructors[0].newInstance(objA, testIIII)
|
||||||
|
|
||||||
/* whittle and instantiate a different A with a new class loader */
|
// whittle and instantiate a different A with a new class loader
|
||||||
val aBuilder2 = cc2.build(aCarpenterSchema)
|
val aBuilder2 = cc2.build(aCarpenterSchema)
|
||||||
val objA2 = aBuilder2.constructors[0].newInstance(testI)
|
val objA2 = aBuilder2.constructors[0].newInstance(testI)
|
||||||
|
|
||||||
bBuilder.constructors[0].newInstance(objA2, testIIII)
|
bBuilder.constructors[0].newInstance(objA2, testIIII)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we remove the neted interface we should get an error as it's impossible
|
// if we remove the nested interface we should get an error as it's impossible
|
||||||
to have a concrete class loaded without having access to all of it's elements */
|
// to have a concrete class loaded without having access to all of it's elements
|
||||||
@Test(expected = UncarpentableException::class)
|
@Test(expected = UncarpentableException::class)
|
||||||
fun memberInterface2() {
|
fun memberInterface2() {
|
||||||
val testI = 25
|
|
||||||
val testIIII = 50
|
|
||||||
|
|
||||||
class A(override val i: Int) : I
|
class A(override val i: Int) : I
|
||||||
class B(override val i: I, override val iiii: Int) : IIII
|
class B(override val i: I, override val iiii: Int) : IIII
|
||||||
|
|
||||||
|
val testI = 25
|
||||||
|
val testIIII = 50
|
||||||
val a = A(testI)
|
val a = A(testI)
|
||||||
val b = B(a, testIIII)
|
val b = B(a, testIIII)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(b))
|
||||||
|
|
||||||
assert(obj.obj is B)
|
assert(obj.obj is B)
|
||||||
|
|
||||||
val serSchema = obj.envelope.schema
|
val serSchema = obj.envelope.schema
|
||||||
|
|
||||||
/*
|
// The classes we're expecting to find:
|
||||||
* The classes we're expecting to find:
|
// * class A
|
||||||
* class A
|
// * class A's interface (class I)
|
||||||
* class A's interface (class I)
|
// * class B
|
||||||
* class B
|
// * class B's interface (class IIII)
|
||||||
* class B's interface (class IIII)
|
|
||||||
*/
|
|
||||||
assertEquals(4, serSchema.types.size)
|
assertEquals(4, serSchema.types.size)
|
||||||
|
|
||||||
/* ignore the return as we expect this to throw */
|
// ignore the return as we expect this to throw
|
||||||
serSchema.corruptName(listOf(
|
serSchema.mangleName(listOf(
|
||||||
classTestName("A"), "${this.javaClass.`package`.name}.I")).carpenterSchema()
|
classTestName("A"), "${this.javaClass.`package`.name}.I")).carpenterSchema()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun interfaceAndImplementation() {
|
fun interfaceAndImplementation() {
|
||||||
val testI = 25
|
|
||||||
|
|
||||||
class A(override val i: Int) : I
|
class A(override val i: Int) : I
|
||||||
|
|
||||||
|
val testI = 25
|
||||||
val a = A(testI)
|
val a = A(testI)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
|
|
||||||
val serSchema = obj.envelope.schema
|
val serSchema = obj.envelope.schema
|
||||||
|
|
||||||
/*
|
// The classes we're expecting to find:
|
||||||
* The classes we're expecting to find:
|
// * class A
|
||||||
* class A
|
// * class A's interface (class I)
|
||||||
* class A's interface (class I)
|
|
||||||
*/
|
|
||||||
assertEquals(2, serSchema.types.size)
|
assertEquals(2, serSchema.types.size)
|
||||||
|
|
||||||
val amqpSchema = serSchema.corruptName(listOf(classTestName("A"), "${this.javaClass.`package`.name}.I"))
|
val amqpSchema = serSchema.mangleName(listOf(classTestName("A"), "${this.javaClass.`package`.name}.I"))
|
||||||
|
val aName = mangleName(classTestName("A"))
|
||||||
val aName = corruptName(classTestName("A"))
|
val iName = mangleName("${this.javaClass.`package`.name}.I")
|
||||||
val iName = corruptName("${this.javaClass.`package`.name}.I")
|
|
||||||
|
|
||||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||||
|
|
||||||
/* whilst there are two unknown classes within the envelope A depends on I so we can't construct a
|
// whilst there are two unknown classes within the envelope A depends on I so we can't construct a
|
||||||
schema for A until we have for I */
|
// schema for A until we have for I
|
||||||
assertEquals(1, carpenterSchema.size)
|
assertEquals(1, carpenterSchema.size)
|
||||||
assertNotEquals(null, carpenterSchema.carpenterSchemas.find { it.name == iName })
|
assertNotEquals(null, carpenterSchema.carpenterSchemas.find { it.name == iName })
|
||||||
|
|
||||||
/* since we can't build A it should list I as a dependency*/
|
// since we can't build A it should list I as a dependency
|
||||||
assert(aName in carpenterSchema.dependencies)
|
assert(aName in carpenterSchema.dependencies)
|
||||||
assertEquals(1, carpenterSchema.dependencies[aName]!!.second.size)
|
assertEquals(1, carpenterSchema.dependencies[aName]!!.second.size)
|
||||||
assertEquals(iName, carpenterSchema.dependencies[aName]!!.second[0])
|
assertEquals(iName, carpenterSchema.dependencies[aName]!!.second[0])
|
||||||
|
|
||||||
/* and conversly I should have A listed as a dependent */
|
// and conversly I should have A listed as a dependent
|
||||||
assert(iName in carpenterSchema.dependsOn)
|
assert(iName in carpenterSchema.dependsOn)
|
||||||
assertEquals(1, carpenterSchema.dependsOn[iName]!!.size)
|
assertEquals(1, carpenterSchema.dependsOn[iName]!!.size)
|
||||||
assertEquals(aName, carpenterSchema.dependsOn[iName]!![0])
|
assertEquals(aName, carpenterSchema.dependsOn[iName]!![0])
|
||||||
|
|
||||||
val mc = MetaCarpenter(carpenterSchema)
|
val mc = MetaCarpenter(carpenterSchema)
|
||||||
|
|
||||||
mc.build()
|
mc.build()
|
||||||
|
|
||||||
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
||||||
@ -396,29 +352,26 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun twoInterfacesAndImplementation() {
|
fun twoInterfacesAndImplementation() {
|
||||||
val testI = 69
|
|
||||||
val testII = 96
|
|
||||||
|
|
||||||
class A(override val i: Int, override val ii: Int) : I, II
|
class A(override val i: Int, override val ii: Int) : I, II
|
||||||
|
|
||||||
|
val testI = 69
|
||||||
|
val testII = 96
|
||||||
val a = A(testI, testII)
|
val a = A(testI, testII)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
val amqpSchema = obj.envelope.schema.corruptName(listOf(
|
val amqpSchema = obj.envelope.schema.mangleName(listOf(
|
||||||
classTestName("A"),
|
classTestName("A"),
|
||||||
"${this.javaClass.`package`.name}.I",
|
"${this.javaClass.`package`.name}.I",
|
||||||
"${this.javaClass.`package`.name}.II"))
|
"${this.javaClass.`package`.name}.II"))
|
||||||
|
|
||||||
val aName = corruptName(classTestName("A"))
|
val aName = mangleName(classTestName("A"))
|
||||||
val iName = corruptName("${this.javaClass.`package`.name}.I")
|
val iName = mangleName("${this.javaClass.`package`.name}.I")
|
||||||
val iiName = corruptName("${this.javaClass.`package`.name}.II")
|
val iiName = mangleName("${this.javaClass.`package`.name}.II")
|
||||||
|
|
||||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||||
|
|
||||||
/* there is nothing preventing us from carpenting up the two interfaces so
|
// there is nothing preventing us from carpenting up the two interfaces so
|
||||||
our initial list should contain both interface with A being dependent on both
|
// our initial list should contain both interface with A being dependent on both
|
||||||
and each having A as a dependent */
|
// and each having A as a dependent
|
||||||
assertEquals(2, carpenterSchema.carpenterSchemas.size)
|
assertEquals(2, carpenterSchema.carpenterSchemas.size)
|
||||||
assertNotNull(carpenterSchema.carpenterSchemas.find { it.name == iName })
|
assertNotNull(carpenterSchema.carpenterSchemas.find { it.name == iName })
|
||||||
assertNotNull(carpenterSchema.carpenterSchemas.find { it.name == iiName })
|
assertNotNull(carpenterSchema.carpenterSchemas.find { it.name == iiName })
|
||||||
@ -438,8 +391,8 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiName })
|
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiName })
|
||||||
|
|
||||||
val mc = MetaCarpenter(carpenterSchema)
|
val mc = MetaCarpenter(carpenterSchema)
|
||||||
|
|
||||||
mc.build()
|
mc.build()
|
||||||
|
|
||||||
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
||||||
assertEquals(0, mc.schemas.dependencies.size)
|
assertEquals(0, mc.schemas.dependencies.size)
|
||||||
assertEquals(0, mc.schemas.dependsOn.size)
|
assertEquals(0, mc.schemas.dependsOn.size)
|
||||||
@ -451,58 +404,56 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun nestedInterfacesAndImplementation() {
|
fun nestedInterfacesAndImplementation() {
|
||||||
val testI = 7
|
|
||||||
val testIII = 11
|
|
||||||
|
|
||||||
class A(override val i: Int, override val iii: Int) : III
|
class A(override val i: Int, override val iii: Int) : III
|
||||||
|
|
||||||
|
val testI = 7
|
||||||
|
val testIII = 11
|
||||||
val a = A(testI, testIII)
|
val a = A(testI, testIII)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
val amqpSchema = obj.envelope.schema.corruptName(listOf(
|
val amqpSchema = obj.envelope.schema.mangleName(listOf(
|
||||||
classTestName("A"),
|
classTestName("A"),
|
||||||
"${this.javaClass.`package`.name}.I",
|
"${this.javaClass.`package`.name}.I",
|
||||||
"${this.javaClass.`package`.name}.III"))
|
"${this.javaClass.`package`.name}.III"))
|
||||||
|
|
||||||
val aName = corruptName(classTestName("A"))
|
val aName = mangleName(classTestName("A"))
|
||||||
val iName = corruptName("${this.javaClass.`package`.name}.I")
|
val iName = mangleName("${this.javaClass.`package`.name}.I")
|
||||||
val iiiName = corruptName("${this.javaClass.`package`.name}.III")
|
val iiiName = mangleName("${this.javaClass.`package`.name}.III")
|
||||||
|
|
||||||
val carpenterSchema = amqpSchema.carpenterSchema()
|
val carpenterSchema = amqpSchema.carpenterSchema()
|
||||||
|
|
||||||
/* Since A depends on III and III extends I we will have to construct them
|
// Since A depends on III and III extends I we will have to construct them
|
||||||
* in that reverse order (I -> III -> A) */
|
// in that reverse order (I -> III -> A)
|
||||||
assertEquals(1, carpenterSchema.carpenterSchemas.size)
|
assertEquals(1, carpenterSchema.carpenterSchemas.size)
|
||||||
assertNotNull(carpenterSchema.carpenterSchemas.find { it.name == iName })
|
assertNotNull(carpenterSchema.carpenterSchemas.find { it.name == iName })
|
||||||
assertNull(carpenterSchema.carpenterSchemas.find { it.name == iiiName })
|
assertNull(carpenterSchema.carpenterSchemas.find { it.name == iiiName })
|
||||||
assertNull(carpenterSchema.carpenterSchemas.find { it.name == aName })
|
assertNull(carpenterSchema.carpenterSchemas.find { it.name == aName })
|
||||||
|
|
||||||
/* I has III as a direct dependent and A as an indirect one */
|
// I has III as a direct dependent and A as an indirect one
|
||||||
assert(iName in carpenterSchema.dependsOn)
|
assert(iName in carpenterSchema.dependsOn)
|
||||||
assertEquals(2, carpenterSchema.dependsOn[iName]?.size)
|
assertEquals(2, carpenterSchema.dependsOn[iName]?.size)
|
||||||
assertNotNull(carpenterSchema.dependsOn[iName]?.find({ it == iiiName }))
|
assertNotNull(carpenterSchema.dependsOn[iName]?.find({ it == iiiName }))
|
||||||
assertNotNull(carpenterSchema.dependsOn[iName]?.find({ it == aName }))
|
assertNotNull(carpenterSchema.dependsOn[iName]?.find({ it == aName }))
|
||||||
|
|
||||||
/* III has A as a dependent */
|
// III has A as a dependent
|
||||||
assert(iiiName in carpenterSchema.dependsOn)
|
assert(iiiName in carpenterSchema.dependsOn)
|
||||||
assertEquals(1, carpenterSchema.dependsOn[iiiName]?.size)
|
assertEquals(1, carpenterSchema.dependsOn[iiiName]?.size)
|
||||||
assertNotNull(carpenterSchema.dependsOn[iiiName]?.find { it == aName })
|
assertNotNull(carpenterSchema.dependsOn[iiiName]?.find { it == aName })
|
||||||
|
|
||||||
/* converly III depends on I */
|
// conversly III depends on I
|
||||||
assert(iiiName in carpenterSchema.dependencies)
|
assert(iiiName in carpenterSchema.dependencies)
|
||||||
assertEquals(1, carpenterSchema.dependencies[iiiName]!!.second.size)
|
assertEquals(1, carpenterSchema.dependencies[iiiName]!!.second.size)
|
||||||
assertNotNull(carpenterSchema.dependencies[iiiName]!!.second.find { it == iName })
|
assertNotNull(carpenterSchema.dependencies[iiiName]!!.second.find { it == iName })
|
||||||
|
|
||||||
/* and A depends on III and I*/
|
// and A depends on III and I
|
||||||
assert(aName in carpenterSchema.dependencies)
|
assert(aName in carpenterSchema.dependencies)
|
||||||
assertEquals(2, carpenterSchema.dependencies[aName]!!.second.size)
|
assertEquals(2, carpenterSchema.dependencies[aName]!!.second.size)
|
||||||
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiiName })
|
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iiiName })
|
||||||
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iName })
|
assertNotNull(carpenterSchema.dependencies[aName]!!.second.find { it == iName })
|
||||||
|
|
||||||
val mc = MetaCarpenter(carpenterSchema)
|
val mc = MetaCarpenter(carpenterSchema)
|
||||||
|
|
||||||
mc.build()
|
mc.build()
|
||||||
|
|
||||||
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
assertEquals(0, mc.schemas.carpenterSchemas.size)
|
||||||
assertEquals(0, mc.schemas.dependencies.size)
|
assertEquals(0, mc.schemas.dependencies.size)
|
||||||
assertEquals(0, mc.schemas.dependsOn.size)
|
assertEquals(0, mc.schemas.dependsOn.size)
|
||||||
@ -512,5 +463,3 @@ class InheritanceSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
assert(iiiName in mc.objects)
|
assert(iiiName in mc.objects)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package net.corda.core.serialization.carpenter
|
package net.corda.core.serialization.carpenter
|
||||||
|
|
||||||
import net.corda.core.serialization.carpenter.test.AmqpCarpenterBase
|
import net.corda.core.serialization.carpenter.test.AmqpCarpenterBase
|
||||||
import net.corda.core.serialization.carpenter.CarpenterSchemas
|
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.serialization.amqp.*
|
import net.corda.core.serialization.amqp.*
|
||||||
|
|
||||||
@ -13,14 +12,12 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun twoInts() {
|
fun twoInts() {
|
||||||
val testA = 10
|
|
||||||
val testB = 20
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: Int, val b: Int)
|
data class A(val a: Int, val b: Int)
|
||||||
|
|
||||||
var a = A(testA, testB)
|
val testA = 10
|
||||||
|
val testB = 20
|
||||||
|
val a = A(testA, testB)
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
@ -31,7 +28,7 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
assertEquals(1, obj.envelope.schema.types.size)
|
assertEquals(1, obj.envelope.schema.types.size)
|
||||||
assert(obj.envelope.schema.types[0] is CompositeType)
|
assert(obj.envelope.schema.types[0] is CompositeType)
|
||||||
|
|
||||||
var amqpSchema = obj.envelope.schema.types[0] as CompositeType
|
val amqpSchema = obj.envelope.schema.types[0] as CompositeType
|
||||||
|
|
||||||
assertEquals(2, amqpSchema.fields.size)
|
assertEquals(2, amqpSchema.fields.size)
|
||||||
assertEquals("a", amqpSchema.fields[0].name)
|
assertEquals("a", amqpSchema.fields[0].name)
|
||||||
@ -48,7 +45,6 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
assertNotEquals(null, aSchema)
|
assertNotEquals(null, aSchema)
|
||||||
|
|
||||||
val pinochio = ClassCarpenter().build(aSchema!!)
|
val pinochio = ClassCarpenter().build(aSchema!!)
|
||||||
|
|
||||||
val p = pinochio.constructors[0].newInstance(testA, testB)
|
val p = pinochio.constructors[0].newInstance(testA, testB)
|
||||||
|
|
||||||
assertEquals(pinochio.getMethod("getA").invoke(p), amqpObj.a)
|
assertEquals(pinochio.getMethod("getA").invoke(p), amqpObj.a)
|
||||||
@ -57,14 +53,12 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun intAndStr() {
|
fun intAndStr() {
|
||||||
val testA = 10
|
|
||||||
val testB = "twenty"
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: Int, val b: String)
|
data class A(val a: Int, val b: String)
|
||||||
|
|
||||||
|
val testA = 10
|
||||||
|
val testB = "twenty"
|
||||||
val a = A(testA, testB)
|
val a = A(testA, testB)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
@ -92,7 +86,6 @@ class MultiMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
assertNotEquals(null, aSchema)
|
assertNotEquals(null, aSchema)
|
||||||
|
|
||||||
val pinochio = ClassCarpenter().build(aSchema!!)
|
val pinochio = ClassCarpenter().build(aSchema!!)
|
||||||
|
|
||||||
val p = pinochio.constructors[0].newInstance(testA, testB)
|
val p = pinochio.constructors[0].newInstance(testA, testB)
|
||||||
|
|
||||||
assertEquals(pinochio.getMethod("getA").invoke(p), amqpObj.a)
|
assertEquals(pinochio.getMethod("getA").invoke(p), amqpObj.a)
|
||||||
|
@ -1,23 +1,19 @@
|
|||||||
package net.corda.core.serialization.carpenter
|
package net.corda.core.serialization.carpenter
|
||||||
|
|
||||||
import net.corda.core.serialization.carpenter.test.AmqpCarpenterBase
|
import net.corda.core.serialization.carpenter.test.AmqpCarpenterBase
|
||||||
import net.corda.core.serialization.carpenter.CarpenterSchemas
|
|
||||||
import net.corda.core.serialization.CordaSerializable
|
import net.corda.core.serialization.CordaSerializable
|
||||||
import net.corda.core.serialization.amqp.*
|
import net.corda.core.serialization.amqp.*
|
||||||
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
|
||||||
class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun singleInteger() {
|
fun singleInteger() {
|
||||||
val test = 10
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: Int)
|
data class A(val a: Int)
|
||||||
|
|
||||||
|
val test = 10
|
||||||
val a = A(test)
|
val a = A(test)
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
@ -39,7 +35,6 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||||
val aBuilder = ClassCarpenter().build(aSchema)
|
val aBuilder = ClassCarpenter().build(aSchema)
|
||||||
|
|
||||||
val p = aBuilder.constructors[0].newInstance(test)
|
val p = aBuilder.constructors[0].newInstance(test)
|
||||||
|
|
||||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||||
@ -47,11 +42,10 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun singleString() {
|
fun singleString() {
|
||||||
val test = "ten"
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: String)
|
data class A(val a: String)
|
||||||
|
|
||||||
|
val test = "ten"
|
||||||
val a = A(test)
|
val a = A(test)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
@ -64,13 +58,11 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
assert(obj.envelope.schema.types[0] is CompositeType)
|
assert(obj.envelope.schema.types[0] is CompositeType)
|
||||||
|
|
||||||
val amqpSchema = obj.envelope.schema.types[0] as CompositeType
|
val amqpSchema = obj.envelope.schema.types[0] as CompositeType
|
||||||
|
|
||||||
val carpenterSchema = CarpenterSchemas.newInstance()
|
val carpenterSchema = CarpenterSchemas.newInstance()
|
||||||
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
amqpSchema.carpenterSchema(carpenterSchemas = carpenterSchema, force = true)
|
||||||
|
|
||||||
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
val aSchema = carpenterSchema.carpenterSchemas.find { it.name == classTestName("A") }!!
|
||||||
val aBuilder = ClassCarpenter().build(aSchema)
|
val aBuilder = ClassCarpenter().build(aSchema)
|
||||||
|
|
||||||
val p = aBuilder.constructors[0].newInstance(test)
|
val p = aBuilder.constructors[0].newInstance(test)
|
||||||
|
|
||||||
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
assertEquals(aBuilder.getMethod("getA").invoke(p), amqpObj.a)
|
||||||
@ -78,13 +70,11 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun singleLong() {
|
fun singleLong() {
|
||||||
val test = 10L
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: Long)
|
data class A(val a: Long)
|
||||||
|
|
||||||
|
val test = 10L
|
||||||
val a = A(test)
|
val a = A(test)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
@ -112,13 +102,11 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun singleShort() {
|
fun singleShort() {
|
||||||
val test = 10.toShort()
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: Short)
|
data class A(val a: Short)
|
||||||
|
|
||||||
|
val test = 10.toShort()
|
||||||
val a = A(test)
|
val a = A(test)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
@ -146,13 +134,11 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun singleDouble() {
|
fun singleDouble() {
|
||||||
val test = 10.0
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: Double)
|
data class A(val a: Double)
|
||||||
|
|
||||||
|
val test = 10.0
|
||||||
val a = A(test)
|
val a = A(test)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
@ -180,13 +166,11 @@ class SingleMemberCompositeSchemaToClassCarpenterTests : AmqpCarpenterBase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun singleFloat() {
|
fun singleFloat() {
|
||||||
val test: Float = 10.0F
|
|
||||||
|
|
||||||
@CordaSerializable
|
@CordaSerializable
|
||||||
data class A(val a: Float)
|
data class A(val a: Float)
|
||||||
|
|
||||||
|
val test: Float = 10.0F
|
||||||
val a = A(test)
|
val a = A(test)
|
||||||
|
|
||||||
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
val obj = DeserializationInput(factory).deserializeAndReturnEnvelope(serialise(a))
|
||||||
|
|
||||||
assert(obj.obj is A)
|
assert(obj.obj is A)
|
||||||
|
Loading…
Reference in New Issue
Block a user