From 4009974d090a25ad3c50f6a9977190820450723b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3gvan=20Olsen?= Date: Mon, 4 Nov 2019 17:05:02 +0000 Subject: [PATCH] #55: Support for java arrays --- build.gradle | 2 +- .../com/apurebase/kgraphql/Extensions.kt | 6 ++-- .../execution/ParallelRequestExecutor.kt | 35 +++++++++---------- .../schema/structure2/SchemaCompilation.kt | 7 ++-- .../kgraphql/schema/SchemaBuilderTest.kt | 18 ++++++++-- 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/build.gradle b/build.gradle index 9a43fce5..d1dd16b6 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group 'com.apurebase' -version '0.8.0' +version '0.8.1' buildscript { diff --git a/src/main/kotlin/com/apurebase/kgraphql/Extensions.kt b/src/main/kotlin/com/apurebase/kgraphql/Extensions.kt index 1dd72fbe..00309f8e 100644 --- a/src/main/kotlin/com/apurebase/kgraphql/Extensions.kt +++ b/src/main/kotlin/com/apurebase/kgraphql/Extensions.kt @@ -20,11 +20,11 @@ fun KParameter.isNotNullable() = !type.isMarkedNullable fun KClass<*>.isIterable() = isSubclassOf(Iterable::class) -fun KType.isIterable() = jvmErasure.isIterable() +fun KType.isIterable() = jvmErasure.isIterable() || toString().startsWith("kotlin.Array") fun KType.getIterableElementType(): KType? { - require(jvmErasure.isIterable()) { "KType $this is not collection type" } + require(isIterable()) { "KType $this is not collection type" } return arguments.firstOrNull()?.type ?: throw NoSuchElementException("KType $this has no type arguments") } -fun not(boolean: Boolean) = !boolean \ No newline at end of file +fun not(boolean: Boolean) = !boolean diff --git a/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt b/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt index 4326c894..31804739 100755 --- a/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt +++ b/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ParallelRequestExecutor.kt @@ -137,12 +137,16 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor, Coro value == null -> createNullNode(node, returnType) //check value, not returnType, because this method can be invoked with element value - value is Collection<*> -> { + value is Collection<*> || value is Array<*> -> { + val values: Collection<*> = when (value) { + is Array<*> -> value.toList() + else -> value as Collection<*> + } if (returnType.isList()) { - val valuesMap = value.toMapAsync { + val valuesMap = values.toMapAsync { createNode(ctx, it, node, returnType.unwrapList()) } - value.fold(jsonNodeFactory.arrayNode(value.size)) { array, v -> + values.fold(jsonNodeFactory.arrayNode(values.size)) { array, v -> array.add(valuesMap[v]) } } else { @@ -166,8 +170,7 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor, Coro } private fun createSimpleValueNode(returnType: Type, value: T): JsonNode { - val unwrapped = returnType.unwrapped() - return when (unwrapped) { + return when (val unwrapped = returnType.unwrapped()) { is Type.Scalar<*> -> { serializeScalar(jsonNodeFactory, unwrapped, value) } @@ -252,20 +255,14 @@ class ParallelRequestExecutor(val schema: DefaultSchema) : RequestExecutor, Coro if (include) { when (field) { is Field.Kotlin<*, *> -> { - field.kProperty as KProperty1 - val rawValue = field.kProperty.get(parentValue) - val value: Any? - value = if (field.transformation != null) { - field.transformation.invoke( - funName = field.name, - receiver = rawValue, - inputValues = field.arguments, - args = node.arguments, - ctx = ctx - ) - } else { - rawValue - } + val rawValue = (field.kProperty as KProperty1).get(parentValue) + val value: Any? = field.transformation?.invoke( + funName = field.name, + receiver = rawValue, + inputValues = field.arguments, + args = node.arguments, + ctx = ctx + ) ?: rawValue return createNode(ctx, value, node, field.returnType) } is Field.Function<*, *> -> { diff --git a/src/main/kotlin/com/apurebase/kgraphql/schema/structure2/SchemaCompilation.kt b/src/main/kotlin/com/apurebase/kgraphql/schema/structure2/SchemaCompilation.kt index 156fc634..3a6e4870 100755 --- a/src/main/kotlin/com/apurebase/kgraphql/schema/structure2/SchemaCompilation.kt +++ b/src/main/kotlin/com/apurebase/kgraphql/schema/structure2/SchemaCompilation.kt @@ -161,8 +161,11 @@ class SchemaCompilation( } private fun handleCollectionType(kType: KType, typeCategory: TypeCategory): Type { - val type = kType.getIterableElementType() - ?: throw SchemaException("Cannot handle collection without element type") + val type = when { + kType.getIterableElementType() != null -> kType.getIterableElementType() + kType.arguments.size == 1 -> kType.arguments.first().type + else -> null + } ?: throw throw SchemaException("Cannot handle collection without element type") val nullableListType = Type.AList(handleSimpleType(type, typeCategory)) return applyNullability(kType, nullableListType) diff --git a/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt b/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt index 424a2fe1..2497af01 100644 --- a/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt +++ b/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaBuilderTest.kt @@ -254,12 +254,26 @@ class SchemaBuilderTest { expect("Generic types are not supported by GraphQL, found () -> kotlin.Int"){ KGraphQL.schema { query("lambda"){ - resolver { -> LambdaWrapper({ 1 }) } + resolver { -> LambdaWrapper { 1 } } } } } } + @Test + fun `java arrays should be supported`() { + KGraphQL.schema { + query("actors") { + resolver { -> + arrayOf( + Actor("Actor1", 1), + Actor("Actor2", 2) + ) + } + } + }.execute("{actors { name } }").let(::println) + } + class InputOne(val string: String) class InputTwo(val one : InputOne) @@ -575,4 +589,4 @@ class SchemaBuilderTest { assertThat(names, hasItem("TypeAsInput")) assertThat(names, hasItem("TypeAsObject")) } -} \ No newline at end of file +}