From 216386b0a9be6355ea9e7b531b9530d12515fd0a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 22:46:55 +0000 Subject: [PATCH 01/23] Bump ch.qos.logback:logback-classic from 1.3.11 to 1.3.12 Bumps [ch.qos.logback:logback-classic](https://github.com/qos-ch/logback) from 1.3.11 to 1.3.12. - [Commits](https://github.com/qos-ch/logback/compare/v_1.3.11...v_1.3.12) --- updated-dependencies: - dependency-name: ch.qos.logback:logback-classic dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4c9c2da..4f99613c 100644 --- a/pom.xml +++ b/pom.xml @@ -100,7 +100,7 @@ ch.qos.logback logback-classic - 1.3.11 + 1.3.12 javax.servlet From 389ff79e1f0e01308142e32935ca60047f300a3c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Nov 2023 22:47:08 +0000 Subject: [PATCH 02/23] Update dependency ch.qos.logback:logback-classic to v1.3.12 [SECURITY] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4c9c2da..4f99613c 100644 --- a/pom.xml +++ b/pom.xml @@ -100,7 +100,7 @@ ch.qos.logback logback-classic - 1.3.11 + 1.3.12 javax.servlet From eeb478917f71bda869088a6ef88aaad76e067dfa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:44:18 +0000 Subject: [PATCH 03/23] Update actions/setup-java action to v4 --- .github/workflows/pull-request.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/snapshot.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 0aab747e..db43df50 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -12,7 +12,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Setup java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: 'adopt' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index badbff95..cd124cba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,7 +7,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Setup java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' @@ -21,7 +21,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Setup Maven Central - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 36ff1657..34f2fccc 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -10,7 +10,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Setup java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' @@ -24,7 +24,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Setup Maven Central - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '11' distribution: 'adopt' From 77553c9f1108f46cf6e475757355b8fe93ccab6f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:48:50 +0000 Subject: [PATCH 04/23] Update all non-major dependencies --- pom.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 4f99613c..555e0846 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 11 1.8.21 1.7.3 - 2.15.3 + 2.16.0 21.3 1.0.4 @@ -73,7 +73,7 @@ org.apache.commons commons-lang3 - 3.13.0 + 3.14.0 @@ -87,7 +87,7 @@ org.springframework spring-aop - 5.3.30 + 5.3.31 provided @@ -100,7 +100,7 @@ ch.qos.logback logback-classic - 1.3.12 + 1.3.14 javax.servlet @@ -240,7 +240,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.4.0 + 3.5.0 add-test-source @@ -377,7 +377,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.2 + 3.6.3 attach-javadocs From 888aea7dd6a559798e407d7ae256af084b07f530 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:02:56 +0000 Subject: [PATCH 05/23] Update actions/cache action to v4 --- .github/workflows/pull-request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index db43df50..797163af 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -17,7 +17,7 @@ jobs: java-version: ${{ matrix.java }} distribution: 'adopt' - name: Cache Maven packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} From 213f8443aa5529388709c576d2d17df2ad09b375 Mon Sep 17 00:00:00 2001 From: Vojtech Polivka Date: Fri, 27 Sep 2024 14:04:53 -0700 Subject: [PATCH 06/23] Upgrade to v22.x --- pom.xml | 4 ++- .../kickstart/tools/resolver/FieldResolver.kt | 1 + .../tools/resolver/MethodFieldResolver.kt | 25 ++++++++++++------- .../kickstart/tools/EndToEndSpecHelper.kt | 5 ++-- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 555e0846..3525ddc1 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ com.graphql-java graphql-java - ${graphql-java.version} + 22.1 org.antlr @@ -306,6 +306,8 @@ **/*Test.* + + --add-reads kotlin.stdlib=kotlinx.coroutines.core diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt index af88f6aa..440d4473 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt @@ -35,6 +35,7 @@ internal abstract class FieldResolver( } else { { environment -> val source = environment.getSource() + ?: throw ResolverError("Expected source object to not be null!") if (!this.genericType.isAssignableFrom(source.javaClass)) { throw ResolverError("Expected source object to be an instance of '${this.genericType.getRawClass().name}' but instead got '${source.javaClass.name}'") diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt index c76023d5..ebcb4a52 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt @@ -30,7 +30,7 @@ internal class MethodFieldResolver( field: FieldDefinition, search: FieldResolverScanner.Search, options: SchemaParserOptions, - val method: Method + val method: Method, ) : FieldResolver(field, search, options, search.type) { private val log = LoggerFactory.getLogger(javaClass) @@ -53,6 +53,7 @@ internal class MethodFieldResolver( args.add { environment -> val source = environment.getSource() + ?: throw ResolverError("Expected source object to not be null!") if (!expectedType.isAssignableFrom(source.javaClass)) { throw ResolverError("Source type (${source.javaClass.name}) is not expected type (${expectedType.name})!") } @@ -114,6 +115,7 @@ internal class MethodFieldResolver( environment.getContext() // TODO: remove deprecated use in next major release } } + GraphQLContext::class.java -> args.add { environment -> environment.graphQlContext } else -> args.add { environment -> environment } } @@ -139,19 +141,23 @@ internal class MethodFieldResolver( return when (type) { is ListType -> List::class.java.isAssignableFrom(this.genericType.getRawClass(genericParameterType)) && isConcreteScalarType(environment, type.type, this.genericType.unwrapGenericType(genericParameterType)) + is TypeName -> environment.graphQLSchema?.getType(type.name)?.let { isScalar(it) && type.name != "ID" } ?: false + is NonNullType -> isConcreteScalarType(environment, type.type, genericParameterType) else -> false } } override fun scanForMatches(): List { - val unwrappedGenericType = genericType.unwrapGenericType(try { - method.kotlinFunction?.returnType?.javaType ?: method.genericReturnType - } catch (e: InternalError) { - method.genericReturnType - }) + val unwrappedGenericType = genericType.unwrapGenericType( + try { + method.kotlinFunction?.returnType?.javaType ?: method.genericReturnType + } catch (e: InternalError) { + method.genericReturnType + } + ) val returnValueMatch = TypeClassMatcher.PotentialMatch.returnValue(field.type, unwrappedGenericType, genericType, SchemaClassScanner.ReturnValueReference(method)) return field.inputValueDefinitions.mapIndexed { i, inputDefinition -> @@ -187,7 +193,7 @@ internal open class MethodFieldResolverDataFetcher( private val sourceResolver: SourceResolver, method: Method, private val args: List, - private val options: SchemaParserOptions + private val options: SchemaParserOptions, ) : DataFetcher { private val resolverMethod = method @@ -238,11 +244,12 @@ internal open class MethodFieldResolverDataFetcher( } } +// TODO use graphql.schema.LightDataFetcher internal class TrivialMethodFieldResolverDataFetcher( sourceResolver: SourceResolver, method: Method, args: List, - options: SchemaParserOptions + options: SchemaParserOptions, ) : MethodFieldResolverDataFetcher(sourceResolver, method, args, options), TrivialDataFetcher // just to mark it for tracing and optimizations @@ -256,7 +263,7 @@ private fun invoke(method: Method, instance: Any, args: Array): Any? { try { return method.invoke(instance, *args) } catch (e: InvocationTargetException) { - throw e.cause ?: RuntimeException("Unknown error occurred while invoking resolver method") + throw e.cause ?: RuntimeException("Unknown error occurred while invoking resolver method") } } diff --git a/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt b/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt index 329f9ed8..b728f7a0 100644 --- a/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt +++ b/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt @@ -141,8 +141,8 @@ input ItemSearchInput { } input NewItemInput { - name: String! @deprecated - type: Type! @deprecated(reason: "This is a reason") + name: String @deprecated + type: Type @deprecated(reason: "This is a reason") } enum Type { @@ -536,4 +536,3 @@ val uploadScalar: GraphQLScalarType = GraphQLScalarType.newScalar() throw CoercingParseLiteralException("Must use variables to specify Upload values") } }).build() - From 5b309bb27a7034e9c1af9724a9ed010b58bc2317 Mon Sep 17 00:00:00 2001 From: Vojtech Polivka Date: Tue, 1 Oct 2024 08:28:19 -0700 Subject: [PATCH 07/23] Upgrade to v22.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3525ddc1..acaf46f9 100644 --- a/pom.xml +++ b/pom.xml @@ -45,7 +45,7 @@ com.graphql-java graphql-java - 22.1 + 22.3 org.antlr From f19e0369b6b273e789d40c4544884ea897f43688 Mon Sep 17 00:00:00 2001 From: Vojtech Polivka Date: Tue, 1 Oct 2024 14:54:51 -0700 Subject: [PATCH 08/23] Upgrade other dependencies --- pom.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index acaf46f9..685a8f7a 100644 --- a/pom.xml +++ b/pom.xml @@ -14,10 +14,10 @@ UTF-8 11 - 1.8.21 - 1.7.3 - 2.16.0 - 21.3 + 2.0.20 + 1.9.0 + 2.17.0 + 22.3 1.0.4 ${java.version} @@ -45,7 +45,7 @@ com.graphql-java graphql-java - 22.3 + ${graphql-java.version} org.antlr @@ -83,7 +83,7 @@ 3.29.2-GA provided - + org.springframework spring-aop @@ -91,7 +91,7 @@ provided - + cglib cglib-nodep @@ -134,8 +134,8 @@ org.jetbrains.kotlin kotlin-stdlib - + org.jetbrains annotations @@ -306,7 +306,7 @@ **/*Test.* - + --add-reads kotlin.stdlib=kotlinx.coroutines.core From 834afeaaa0ee0a56fa587550267c8a141492c94c Mon Sep 17 00:00:00 2001 From: Vojtech Polivka Date: Tue, 1 Oct 2024 15:57:38 -0700 Subject: [PATCH 09/23] Use LightDataFetcher where possible --- pom.xml | 2 +- .../kickstart/tools/resolver/FieldResolver.kt | 22 +++- .../tools/resolver/MapFieldResolver.kt | 20 +-- .../tools/resolver/MethodFieldResolver.kt | 117 ++++++++++++------ .../tools/resolver/PropertyFieldResolver.kt | 20 ++- .../graphql/kickstart/tools/util/Utils.kt | 7 +- .../graphql/kickstart/tools/DirectiveTest.kt | 1 + .../MethodFieldResolverDataFetcherTest.kt | 8 ++ .../graphql/kickstart/tools/TestUtils.kt | 14 ++- 9 files changed, 140 insertions(+), 71 deletions(-) diff --git a/pom.xml b/pom.xml index 685a8f7a..2944adf8 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.graphql-java-kickstart graphql-java-tools - 13.1.2-SNAPSHOT + 14.0.0-LOCAL jar GraphQL Java Tools diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt index 440d4473..440820c8 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt @@ -29,13 +29,20 @@ internal abstract class FieldResolver( /** * Add source resolver depending on whether or not this is a resolver method */ - protected fun getSourceResolver(): SourceResolver { + protected fun createSourceResolver(): SourceResolver { return if (this.search.source != null) { - { this.search.source } + SourceResolver { _, _ -> this.search.source } } else { - { environment -> - val source = environment.getSource() - ?: throw ResolverError("Expected source object to not be null!") + SourceResolver { environment, sourceObject -> + val source = if (sourceObject != null) { + // if source object is known, environment is null as an optimization (LightDataFetcher) + sourceObject + } else { + environment + ?: throw ResolverError("Expected DataFetchingEnvironment to not be null!") + environment.getSource() + ?: throw ResolverError("Expected source object to not be null!") + } if (!this.genericType.isAssignableFrom(source.javaClass)) { throw ResolverError("Expected source object to be an instance of '${this.genericType.getRawClass().name}' but instead got '${source.javaClass.name}'") @@ -47,4 +54,7 @@ internal abstract class FieldResolver( } } -internal typealias SourceResolver = (DataFetchingEnvironment) -> Any +fun interface SourceResolver { + + fun resolve(environment: DataFetchingEnvironment?, source: Any?): Any +} diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt index 20e51a24..d7d29f5c 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt @@ -8,6 +8,9 @@ import graphql.kickstart.tools.util.JavaType import graphql.language.FieldDefinition import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.LightDataFetcher +import java.util.function.Supplier /** * @author Nick Weedon @@ -37,7 +40,7 @@ internal class MapFieldResolver( } override fun createDataFetcher(): DataFetcher<*> { - return MapFieldResolverDataFetcher(getSourceResolver(), field.name) + return MapFieldResolverDataFetcher(createSourceResolver(), field.name) } override fun scanForMatches(): List { @@ -49,15 +52,18 @@ internal class MapFieldResolver( internal class MapFieldResolverDataFetcher( private val sourceResolver: SourceResolver, - private val key: String -) : DataFetcher { + private val key: String, +) : LightDataFetcher { - override fun get(environment: DataFetchingEnvironment): Any? { - val resolvedSourceObject = sourceResolver(environment) - if (resolvedSourceObject is Map<*, *>) { - return resolvedSourceObject[key] + override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any, environmentSupplier: Supplier): Any? { + if (sourceObject is Map<*, *>) { + return sourceObject[key] } else { throw RuntimeException("MapFieldResolver attempt to fetch a field from an object instance that was not a map") } } + + override fun get(environment: DataFetchingEnvironment): Any? { + return get(environment.fieldDefinition, sourceResolver.resolve(environment, null), { environment }) + } } diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt index ebcb4a52..3ae84c0c 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt @@ -2,7 +2,6 @@ package graphql.kickstart.tools.resolver import com.fasterxml.jackson.core.type.TypeReference import graphql.GraphQLContext -import graphql.TrivialDataFetcher import graphql.kickstart.tools.* import graphql.kickstart.tools.SchemaParserOptions.GenericWrapper import graphql.kickstart.tools.util.JavaType @@ -12,12 +11,15 @@ import graphql.kickstart.tools.util.unwrap import graphql.language.* import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLFieldDefinition import graphql.schema.GraphQLTypeUtil.isScalar +import graphql.schema.LightDataFetcher import kotlinx.coroutines.future.future import org.slf4j.LoggerFactory import java.lang.reflect.InvocationTargetException import java.lang.reflect.Method import java.util.* +import java.util.function.Supplier import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn import kotlin.reflect.full.valueParameters import kotlin.reflect.jvm.javaType @@ -122,9 +124,9 @@ internal class MethodFieldResolver( } return if (args.isEmpty() && isTrivialDataFetcher(this.method)) { - TrivialMethodFieldResolverDataFetcher(getSourceResolver(), this.method, args, options) + LightMethodFieldResolverDataFetcher(createSourceResolver(), this.method, options) } else { - MethodFieldResolverDataFetcher(getSourceResolver(), this.method, args, options) + MethodFieldResolverDataFetcher(createSourceResolver(), this.method, args, options) } } @@ -189,69 +191,102 @@ internal class MethodFieldResolver( override fun toString() = "MethodFieldResolver{method=$method}" } -internal open class MethodFieldResolverDataFetcher( +internal class MethodFieldResolverDataFetcher( private val sourceResolver: SourceResolver, - method: Method, + private val method: Method, private val args: List, private val options: SchemaParserOptions, ) : DataFetcher { - private val resolverMethod = method - private val isSuspendFunction = try { - method.kotlinFunction?.isSuspend == true - } catch (e: InternalError) { - false - } + private val isSuspendFunction = method.isSuspendFunction() - private class CompareGenericWrappers { - companion object : Comparator { - override fun compare(w1: GenericWrapper, w2: GenericWrapper): Int = when { - w1.type.isAssignableFrom(w2.type) -> 1 - else -> -1 + override fun get(environment: DataFetchingEnvironment): Any? { + val source = sourceResolver.resolve(environment, null) + val args = this.args.map { it(environment) }.toTypedArray() + + return if (isSuspendFunction) { + environment.coroutineScope().future(options.coroutineContextProvider.provide()) { + invokeSuspend(source, method, args)?.transformWithGenericWrapper(options.genericWrappers, { environment }) } + } else { + invoke(method, source, args)?.transformWithGenericWrapper(options.genericWrappers, { environment }) } } - override fun get(environment: DataFetchingEnvironment): Any? { - val source = sourceResolver(environment) - val args = this.args.map { it(environment) }.toTypedArray() + /** + * Function that returns the object used to fetch the data. It can be a DataFetcher or an entity. + */ + @Suppress("unused") + fun getWrappedFetchingObject(environment: DataFetchingEnvironment): Any { + return sourceResolver.resolve(environment, null) + } +} + +/** + * Similar to [MethodFieldResolverDataFetcher] but for light data fetchers which do not require the environment to be supplied unless suspend functions or + * generic wrappers are used. + */ +internal class LightMethodFieldResolverDataFetcher( + private val sourceResolver: SourceResolver, + private val method: Method, + private val options: SchemaParserOptions, +) : LightDataFetcher { + + private val isSuspendFunction = method.isSuspendFunction() + + override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any, environmentSupplier: Supplier): Any? { + val source = sourceResolver.resolve(null, sourceObject) return if (isSuspendFunction) { - environment.coroutineScope().future(options.coroutineContextProvider.provide()) { - invokeSuspend(source, resolverMethod, args)?.transformWithGenericWrapper(environment) + environmentSupplier.get().coroutineScope().future(options.coroutineContextProvider.provide()) { + invokeSuspend(source, method, emptyArray())?.transformWithGenericWrapper(options.genericWrappers, environmentSupplier) } } else { - invoke(resolverMethod, source, args)?.transformWithGenericWrapper(environment) + invoke(method, source, emptyArray())?.transformWithGenericWrapper(options.genericWrappers, environmentSupplier) } } - private fun Any.transformWithGenericWrapper(environment: DataFetchingEnvironment): Any? { - return options.genericWrappers - .asSequence() - .filter { it.type.isInstance(this) } - .sortedWith(CompareGenericWrappers) - .firstOrNull() - ?.transformer?.invoke(this, environment) ?: this + override fun get(environment: DataFetchingEnvironment): Any? { + return get(environment.fieldDefinition, sourceResolver.resolve(environment, null), { environment }) } /** - * Function that returns the object used to fetch the data. - * It can be a DataFetcher or an entity. + * Function that returns the object used to fetch the data. It can be a DataFetcher or an entity. */ @Suppress("unused") - open fun getWrappedFetchingObject(environment: DataFetchingEnvironment): Any { - return sourceResolver(environment) + fun getWrappedFetchingObject(environment: DataFetchingEnvironment): Any { + return sourceResolver.resolve(environment, null) } } -// TODO use graphql.schema.LightDataFetcher -internal class TrivialMethodFieldResolverDataFetcher( - sourceResolver: SourceResolver, - method: Method, - args: List, - options: SchemaParserOptions, -) : MethodFieldResolverDataFetcher(sourceResolver, method, args, options), - TrivialDataFetcher // just to mark it for tracing and optimizations +private fun Any.transformWithGenericWrapper( + genericWrappers: List, + environmentSupplier: Supplier +): Any? { + return genericWrappers + .asSequence() + .filter { it.type.isInstance(this) } + .sortedWith(CompareGenericWrappers) + .firstOrNull() + ?.transformer?.invoke(this, environmentSupplier.get()) ?: this +} + +private class CompareGenericWrappers { + companion object : Comparator { + override fun compare(w1: GenericWrapper, w2: GenericWrapper): Int = when { + w1.type.isAssignableFrom(w2.type) -> 1 + else -> -1 + } + } +} + +private fun Method.isSuspendFunction(): Boolean { + return try { + this.kotlinFunction?.isSuspend == true + } catch (e: InternalError) { + false + } +} private suspend inline fun invokeSuspend(target: Any, resolverMethod: Method, args: Array): Any? { return suspendCoroutineUninterceptedOrReturn { continuation -> diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt index dba3e9dd..96c8953e 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt @@ -6,7 +6,10 @@ import graphql.kickstart.tools.TypeClassMatcher import graphql.language.FieldDefinition import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.LightDataFetcher import java.lang.reflect.Field +import java.util.function.Supplier /** * @author Andrew Potter @@ -15,11 +18,11 @@ internal class PropertyFieldResolver( field: FieldDefinition, search: FieldResolverScanner.Search, options: SchemaParserOptions, - private val property: Field + private val property: Field, ) : FieldResolver(field, search, options, property.declaringClass) { override fun createDataFetcher(): DataFetcher<*> { - return PropertyFieldResolverDataFetcher(getSourceResolver(), property) + return PropertyFieldResolverDataFetcher(createSourceResolver(), property) } override fun scanForMatches(): List { @@ -28,7 +31,8 @@ internal class PropertyFieldResolver( field.type, property.genericType, genericType, - SchemaClassScanner.FieldTypeReference(property.toString())) + SchemaClassScanner.FieldTypeReference(property.toString()) + ) ) } @@ -37,10 +41,14 @@ internal class PropertyFieldResolver( internal class PropertyFieldResolverDataFetcher( private val sourceResolver: SourceResolver, - private val field: Field -) : DataFetcher { + private val field: Field, +) : LightDataFetcher { + + override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any, environmentSupplier: Supplier): Any? { + return field.get(sourceResolver.resolve(null, sourceObject)) + } override fun get(environment: DataFetchingEnvironment): Any? { - return field.get(sourceResolver(environment)) + return get(environment.fieldDefinition, sourceResolver.resolve(environment, null), { environment }) } } diff --git a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt index ba5e22a5..f1802402 100644 --- a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt +++ b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt @@ -62,11 +62,11 @@ internal fun getDocumentation(node: AbstractNode<*>, options: SchemaParserOption } /** - * Simple heuristic to check is a method is a trivial data fetcher. + * Simple heuristic to check if a method is a trivial data fetcher. * * Requirements are: - * prefixed with get - * must have zero parameters + * - prefixed with get + * - must have zero parameters */ internal fun isTrivialDataFetcher(method: Method): Boolean { return (method.parameterCount == 0 @@ -80,4 +80,3 @@ private fun isBooleanGetter(method: Method) = (method.name.startsWith("is") || method.returnType == Boolean::class.java) internal fun String.snakeToCamelCase(): String = split("_").joinToString(separator = "") { it.replaceFirstChar(Char::titlecase) } - diff --git a/src/test/kotlin/graphql/kickstart/tools/DirectiveTest.kt b/src/test/kotlin/graphql/kickstart/tools/DirectiveTest.kt index 912b3501..79e787cf 100644 --- a/src/test/kotlin/graphql/kickstart/tools/DirectiveTest.kt +++ b/src/test/kotlin/graphql/kickstart/tools/DirectiveTest.kt @@ -10,6 +10,7 @@ import graphql.schema.idl.SchemaDirectiveWiringEnvironment import org.junit.Test class DirectiveTest { + @Test fun `should apply @uppercase directive on field`() { val schema = SchemaParser.newParser() diff --git a/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt b/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt index 481d2a4e..9401feef 100644 --- a/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt +++ b/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt @@ -13,6 +13,8 @@ import graphql.language.TypeName import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment import graphql.schema.DataFetchingEnvironmentImpl +import graphql.schema.GraphQLFieldDefinition +import graphql.schema.GraphQLObjectType import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job @@ -299,6 +301,12 @@ class MethodFieldResolverDataFetcherTest { private fun createEnvironment(source: Any = Object(), arguments: Map = emptyMap(), context: GraphQLContext? = null): DataFetchingEnvironment { return DataFetchingEnvironmentImpl.newDataFetchingEnvironment(buildExecutionContext()) .source(source) + .fieldDefinition( + GraphQLFieldDefinition.newFieldDefinition() + .name("ignored") + .type(GraphQLObjectType.newObject().name("ignored").build()) + .build() + ) .arguments(arguments) .graphQLContext(context) .build() diff --git a/src/test/kotlin/graphql/kickstart/tools/TestUtils.kt b/src/test/kotlin/graphql/kickstart/tools/TestUtils.kt index 2b0ff09b..32473510 100644 --- a/src/test/kotlin/graphql/kickstart/tools/TestUtils.kt +++ b/src/test/kotlin/graphql/kickstart/tools/TestUtils.kt @@ -7,14 +7,16 @@ import graphql.GraphQL private val mapper = ObjectMapper() fun assertNoGraphQlErrors(gql: GraphQL, args: Map = mapOf(), context: Map = mapOf(), closure: () -> String): Map { - val result = gql.execute(ExecutionInput.newExecutionInput() - .query(closure.invoke()) - .graphQLContext(context) - .root(context) - .variables(args)) + val result = gql.execute( + ExecutionInput.newExecutionInput() + .query(closure.invoke()) + .graphQLContext(context) + .root(context) + .variables(args) + ) if (result.errors.isNotEmpty()) { - throw AssertionError("GraphQL result contained errors!\n${result.errors.map { mapper.writeValueAsString(it) }.joinToString { "\n" }}") + throw AssertionError("GraphQL result contained errors!\n${result.errors.map { it.message }.joinToString("\n")}") } return result.getData() as Map From 29cecf01ca6e7eb68fd3d06cdf6b42d3473113d5 Mon Sep 17 00:00:00 2001 From: Vojtech Polivka Date: Wed, 2 Oct 2024 13:06:03 -0700 Subject: [PATCH 10/23] Downgrade build-helper-maven-plugin to 3.4.0 to fix JitPack build --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2944adf8..bd3d7db2 100644 --- a/pom.xml +++ b/pom.xml @@ -240,7 +240,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.5.0 + 3.4.0 add-test-source From 0745d59b4fd261de22655521dd56d3b064eacc6e Mon Sep 17 00:00:00 2001 From: Vojtech Polivka Date: Thu, 3 Oct 2024 09:15:55 -0700 Subject: [PATCH 11/23] Simplify lightweight data fetcher heuristic --- pom.xml | 2 +- .../tools/resolver/MapFieldResolver.kt | 2 +- .../tools/resolver/MethodFieldResolver.kt | 39 +++++++------------ .../tools/resolver/PropertyFieldResolver.kt | 2 +- .../graphql/kickstart/tools/util/Utils.kt | 18 --------- .../graphql/kickstart/tools/util/UtilsTest.kt | 18 --------- 6 files changed, 16 insertions(+), 65 deletions(-) diff --git a/pom.xml b/pom.xml index bd3d7db2..f23b3ee4 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.graphql-java-kickstart graphql-java-tools - 14.0.0-LOCAL + 14.1.0-LOCAL jar GraphQL Java Tools diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt index d7d29f5c..ce48e494 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt @@ -55,7 +55,7 @@ internal class MapFieldResolverDataFetcher( private val key: String, ) : LightDataFetcher { - override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any, environmentSupplier: Supplier): Any? { + override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any?, environmentSupplier: Supplier): Any? { if (sourceObject is Map<*, *>) { return sourceObject[key] } else { diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt index 3ae84c0c..a400b1e7 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt @@ -6,7 +6,6 @@ import graphql.kickstart.tools.* import graphql.kickstart.tools.SchemaParserOptions.GenericWrapper import graphql.kickstart.tools.util.JavaType import graphql.kickstart.tools.util.coroutineScope -import graphql.kickstart.tools.util.isTrivialDataFetcher import graphql.kickstart.tools.util.unwrap import graphql.language.* import graphql.schema.DataFetcher @@ -37,13 +36,9 @@ internal class MethodFieldResolver( private val log = LoggerFactory.getLogger(javaClass) - private val additionalLastArgument = - try { - (method.kotlinFunction?.valueParameters?.size - ?: method.parameterCount) == (field.inputValueDefinitions.size + getIndexOffset() + 1) - } catch (e: InternalError) { - method.parameterCount == (field.inputValueDefinitions.size + getIndexOffset() + 1) - } + private val isSuspendFunction = method.isSuspendFunction() + private val numberOfParameters = method.kotlinFunction?.valueParameters?.size ?: method.parameterCount + private val hasAdditionalParameter = numberOfParameters == (field.inputValueDefinitions.size + getIndexOffset() + 1) override fun createDataFetcher(): DataFetcher<*> { val args = mutableListOf() @@ -100,7 +95,7 @@ internal class MethodFieldResolver( } // Add DataFetchingEnvironment/Context argument - if (this.additionalLastArgument) { + if (this.hasAdditionalParameter) { when (this.method.parameterTypes.last()) { null -> throw ResolverError("Expected at least one argument but got none, this is most likely a bug with graphql-java-tools") options.contextClass -> args.add { environment -> @@ -123,10 +118,12 @@ internal class MethodFieldResolver( } } - return if (args.isEmpty() && isTrivialDataFetcher(this.method)) { - LightMethodFieldResolverDataFetcher(createSourceResolver(), this.method, options) + return if (numberOfParameters > 0 || isSuspendFunction) { + // requires arguments and environment or is a suspend function + MethodFieldResolverDataFetcher(createSourceResolver(), this.method, args, options, isSuspendFunction) } else { - MethodFieldResolverDataFetcher(createSourceResolver(), this.method, args, options) + // if there are no parameters an optimized version of the data fetcher can be used + LightMethodFieldResolverDataFetcher(createSourceResolver(), this.method, options) } } @@ -196,10 +193,9 @@ internal class MethodFieldResolverDataFetcher( private val method: Method, private val args: List, private val options: SchemaParserOptions, + private val isSuspendFunction: Boolean ) : DataFetcher { - private val isSuspendFunction = method.isSuspendFunction() - override fun get(environment: DataFetchingEnvironment): Any? { val source = sourceResolver.resolve(environment, null) val args = this.args.map { it(environment) }.toTypedArray() @@ -223,8 +219,7 @@ internal class MethodFieldResolverDataFetcher( } /** - * Similar to [MethodFieldResolverDataFetcher] but for light data fetchers which do not require the environment to be supplied unless suspend functions or - * generic wrappers are used. + * Similar to [MethodFieldResolverDataFetcher] but for light data fetchers which do not require the environment to be supplied unless generic wrappers are used. */ internal class LightMethodFieldResolverDataFetcher( private val sourceResolver: SourceResolver, @@ -232,18 +227,10 @@ internal class LightMethodFieldResolverDataFetcher( private val options: SchemaParserOptions, ) : LightDataFetcher { - private val isSuspendFunction = method.isSuspendFunction() - - override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any, environmentSupplier: Supplier): Any? { + override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any?, environmentSupplier: Supplier): Any? { val source = sourceResolver.resolve(null, sourceObject) - return if (isSuspendFunction) { - environmentSupplier.get().coroutineScope().future(options.coroutineContextProvider.provide()) { - invokeSuspend(source, method, emptyArray())?.transformWithGenericWrapper(options.genericWrappers, environmentSupplier) - } - } else { - invoke(method, source, emptyArray())?.transformWithGenericWrapper(options.genericWrappers, environmentSupplier) - } + return invoke(method, source, emptyArray())?.transformWithGenericWrapper(options.genericWrappers, environmentSupplier) } override fun get(environment: DataFetchingEnvironment): Any? { diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt index 96c8953e..afbb29f3 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt @@ -44,7 +44,7 @@ internal class PropertyFieldResolverDataFetcher( private val field: Field, ) : LightDataFetcher { - override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any, environmentSupplier: Supplier): Any? { + override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any?, environmentSupplier: Supplier): Any? { return field.get(sourceResolver.resolve(null, sourceObject)) } diff --git a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt index f1802402..e61e88c9 100644 --- a/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt +++ b/src/main/kotlin/graphql/kickstart/tools/util/Utils.kt @@ -61,22 +61,4 @@ internal fun getDocumentation(node: AbstractNode<*>, options: SchemaParserOption .trimIndent() } -/** - * Simple heuristic to check if a method is a trivial data fetcher. - * - * Requirements are: - * - prefixed with get - * - must have zero parameters - */ -internal fun isTrivialDataFetcher(method: Method): Boolean { - return (method.parameterCount == 0 - && ( - method.name.startsWith("get") - || isBooleanGetter(method))) -} - -private fun isBooleanGetter(method: Method) = (method.name.startsWith("is") - && (method.returnType == java.lang.Boolean::class.java) - || method.returnType == Boolean::class.java) - internal fun String.snakeToCamelCase(): String = split("_").joinToString(separator = "") { it.replaceFirstChar(Char::titlecase) } diff --git a/src/test/kotlin/graphql/kickstart/tools/util/UtilsTest.kt b/src/test/kotlin/graphql/kickstart/tools/util/UtilsTest.kt index e8af532e..14cd8dd9 100644 --- a/src/test/kotlin/graphql/kickstart/tools/util/UtilsTest.kt +++ b/src/test/kotlin/graphql/kickstart/tools/util/UtilsTest.kt @@ -1,8 +1,5 @@ package graphql.kickstart.tools.util -import org.junit.Assert -import org.junit.Test - class UtilsTest { @Suppress("unused") @@ -26,19 +23,4 @@ class UtilsTest { private class UtilsTestTrivialDataFetcherBean { val isBooleanPrimitive = false } - - @Test - fun isTrivialDataFetcher() { - val clazz = Bean::class.java - - Assert.assertTrue(isTrivialDataFetcher(clazz.getMethod("getterValid"))) - Assert.assertFalse(isTrivialDataFetcher(clazz.getMethod("getterWithArgument", String::class.java))) - Assert.assertFalse(isTrivialDataFetcher(clazz.getMethod("notAGetter"))) - - Assert.assertFalse(isTrivialDataFetcher(clazz.getMethod("isString"))) - Assert.assertTrue(isTrivialDataFetcher(clazz.getMethod("isJavaBoolean"))) - Assert.assertTrue(isTrivialDataFetcher(clazz.getMethod("isKotlinBoolean"))) - - Assert.assertTrue(isTrivialDataFetcher(UtilsTestTrivialDataFetcherBean::class.java.getMethod("isBooleanPrimitive"))) - } } From edafe516d9e4739f660334bd4ee8e297f4a6a401 Mon Sep 17 00:00:00 2001 From: Vojtech Polivka Date: Thu, 3 Oct 2024 10:12:47 -0700 Subject: [PATCH 12/23] Adjust comments --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f23b3ee4..2479b230 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.graphql-java-kickstart graphql-java-tools - 14.1.0-LOCAL + 14.2.0-LOCAL jar GraphQL Java Tools @@ -240,6 +240,7 @@ org.codehaus.mojo build-helper-maven-plugin + 3.4.0 @@ -306,7 +307,6 @@ **/*Test.* - --add-reads kotlin.stdlib=kotlinx.coroutines.core From e5ca52b724e588aa379c97732740c80f97ed8626 Mon Sep 17 00:00:00 2001 From: Oryan Date: Mon, 7 Oct 2024 13:08:34 -0400 Subject: [PATCH 13/23] Reformat --- .../kickstart/tools/resolver/FieldResolver.kt | 17 ++++------------- .../tools/resolver/MapFieldResolver.kt | 4 ++-- .../tools/resolver/MethodFieldResolver.kt | 12 ++++++------ .../tools/resolver/PropertyFieldResolver.kt | 6 +++--- 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt index 440820c8..addf61d7 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/FieldResolver.kt @@ -1,10 +1,6 @@ package graphql.kickstart.tools.resolver import graphql.kickstart.tools.* -import graphql.kickstart.tools.GenericType -import graphql.kickstart.tools.ResolverError -import graphql.kickstart.tools.ResolverInfo -import graphql.kickstart.tools.TypeClassMatcher import graphql.kickstart.tools.util.JavaType import graphql.language.FieldDefinition import graphql.schema.DataFetcher @@ -34,15 +30,10 @@ internal abstract class FieldResolver( SourceResolver { _, _ -> this.search.source } } else { SourceResolver { environment, sourceObject -> - val source = if (sourceObject != null) { - // if source object is known, environment is null as an optimization (LightDataFetcher) - sourceObject - } else { - environment - ?: throw ResolverError("Expected DataFetchingEnvironment to not be null!") - environment.getSource() - ?: throw ResolverError("Expected source object to not be null!") - } + // if source object is known, environment is null as an optimization (LightDataFetcher) + val source = sourceObject + ?: environment?.getSource() + ?: throw ResolverError("Expected DataFetchingEnvironment and source object to not be null!") if (!this.genericType.isAssignableFrom(source.javaClass)) { throw ResolverError("Expected source object to be an instance of '${this.genericType.getRawClass().name}' but instead got '${source.javaClass.name}'") diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt index ce48e494..e2b635be 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MapFieldResolver.kt @@ -52,7 +52,7 @@ internal class MapFieldResolver( internal class MapFieldResolverDataFetcher( private val sourceResolver: SourceResolver, - private val key: String, + private val key: String ) : LightDataFetcher { override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any?, environmentSupplier: Supplier): Any? { @@ -64,6 +64,6 @@ internal class MapFieldResolverDataFetcher( } override fun get(environment: DataFetchingEnvironment): Any? { - return get(environment.fieldDefinition, sourceResolver.resolve(environment, null), { environment }) + return get(environment.fieldDefinition, sourceResolver.resolve(environment, null)) { environment } } } diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt index a400b1e7..e7f6946d 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt @@ -31,7 +31,7 @@ internal class MethodFieldResolver( field: FieldDefinition, search: FieldResolverScanner.Search, options: SchemaParserOptions, - val method: Method, + val method: Method ) : FieldResolver(field, search, options, search.type) { private val log = LoggerFactory.getLogger(javaClass) @@ -202,10 +202,10 @@ internal class MethodFieldResolverDataFetcher( return if (isSuspendFunction) { environment.coroutineScope().future(options.coroutineContextProvider.provide()) { - invokeSuspend(source, method, args)?.transformWithGenericWrapper(options.genericWrappers, { environment }) + invokeSuspend(source, method, args)?.transformWithGenericWrapper(options.genericWrappers) { environment } } } else { - invoke(method, source, args)?.transformWithGenericWrapper(options.genericWrappers, { environment }) + invoke(method, source, args)?.transformWithGenericWrapper(options.genericWrappers) { environment } } } @@ -224,7 +224,7 @@ internal class MethodFieldResolverDataFetcher( internal class LightMethodFieldResolverDataFetcher( private val sourceResolver: SourceResolver, private val method: Method, - private val options: SchemaParserOptions, + private val options: SchemaParserOptions ) : LightDataFetcher { override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any?, environmentSupplier: Supplier): Any? { @@ -234,7 +234,7 @@ internal class LightMethodFieldResolverDataFetcher( } override fun get(environment: DataFetchingEnvironment): Any? { - return get(environment.fieldDefinition, sourceResolver.resolve(environment, null), { environment }) + return get(environment.fieldDefinition, sourceResolver.resolve(environment, null)) { environment } } /** @@ -249,7 +249,7 @@ internal class LightMethodFieldResolverDataFetcher( private fun Any.transformWithGenericWrapper( genericWrappers: List, environmentSupplier: Supplier -): Any? { +): Any { return genericWrappers .asSequence() .filter { it.type.isInstance(this) } diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt index afbb29f3..6151181a 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/PropertyFieldResolver.kt @@ -18,7 +18,7 @@ internal class PropertyFieldResolver( field: FieldDefinition, search: FieldResolverScanner.Search, options: SchemaParserOptions, - private val property: Field, + private val property: Field ) : FieldResolver(field, search, options, property.declaringClass) { override fun createDataFetcher(): DataFetcher<*> { @@ -41,7 +41,7 @@ internal class PropertyFieldResolver( internal class PropertyFieldResolverDataFetcher( private val sourceResolver: SourceResolver, - private val field: Field, + private val field: Field ) : LightDataFetcher { override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any?, environmentSupplier: Supplier): Any? { @@ -49,6 +49,6 @@ internal class PropertyFieldResolverDataFetcher( } override fun get(environment: DataFetchingEnvironment): Any? { - return get(environment.fieldDefinition, sourceResolver.resolve(environment, null), { environment }) + return get(environment.fieldDefinition, sourceResolver.resolve(environment, null)) { environment } } } From e9074ec27b8a90f0e99793e4e2f910b723bc38a2 Mon Sep 17 00:00:00 2001 From: Oryan Date: Tue, 8 Oct 2024 10:20:47 -0400 Subject: [PATCH 14/23] Make nullable --- .../kickstart/tools/resolver/MethodFieldResolver.kt | 2 +- .../kickstart/tools/MethodFieldResolverDataFetcherTest.kt | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt index e7f6946d..76fc7f19 100644 --- a/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt +++ b/src/main/kotlin/graphql/kickstart/tools/resolver/MethodFieldResolver.kt @@ -227,7 +227,7 @@ internal class LightMethodFieldResolverDataFetcher( private val options: SchemaParserOptions ) : LightDataFetcher { - override fun get(fieldDefinition: GraphQLFieldDefinition, sourceObject: Any?, environmentSupplier: Supplier): Any? { + override fun get(fieldDefinition: GraphQLFieldDefinition?, sourceObject: Any?, environmentSupplier: Supplier): Any? { val source = sourceResolver.resolve(null, sourceObject) return invoke(method, source, emptyArray())?.transformWithGenericWrapper(options.genericWrappers, environmentSupplier) diff --git a/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt b/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt index 9401feef..481d2a4e 100644 --- a/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt +++ b/src/test/kotlin/graphql/kickstart/tools/MethodFieldResolverDataFetcherTest.kt @@ -13,8 +13,6 @@ import graphql.language.TypeName import graphql.schema.DataFetcher import graphql.schema.DataFetchingEnvironment import graphql.schema.DataFetchingEnvironmentImpl -import graphql.schema.GraphQLFieldDefinition -import graphql.schema.GraphQLObjectType import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job @@ -301,12 +299,6 @@ class MethodFieldResolverDataFetcherTest { private fun createEnvironment(source: Any = Object(), arguments: Map = emptyMap(), context: GraphQLContext? = null): DataFetchingEnvironment { return DataFetchingEnvironmentImpl.newDataFetchingEnvironment(buildExecutionContext()) .source(source) - .fieldDefinition( - GraphQLFieldDefinition.newFieldDefinition() - .name("ignored") - .type(GraphQLObjectType.newObject().name("ignored").build()) - .build() - ) .arguments(arguments) .graphQLContext(context) .build() From 30eb9bd6426931de8be5c6678cf3cd27cb293fdd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:58:17 +0000 Subject: [PATCH 15/23] Update peter-evans/create-pull-request action to v7 --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cd124cba..704326fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: GPG_PASSPHRASE: ${{ secrets.GPG_SIGNING_PASSWORD }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create Release PR - uses: peter-evans/create-pull-request@v5 + uses: peter-evans/create-pull-request@v7 with: branch: version-release title: Version Release From d408078bcca217151d0bbb8478acee8532279109 Mon Sep 17 00:00:00 2001 From: Oryan Date: Tue, 8 Oct 2024 11:09:27 -0400 Subject: [PATCH 16/23] Add comment --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 2479b230..e9236fa1 100644 --- a/pom.xml +++ b/pom.xml @@ -307,6 +307,7 @@ **/*Test.* + --add-reads kotlin.stdlib=kotlinx.coroutines.core From fd06ad24924b03be3f90479158237613e1673696 Mon Sep 17 00:00:00 2001 From: Oryan Date: Tue, 8 Oct 2024 11:11:56 -0400 Subject: [PATCH 17/23] Revert version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9236fa1..b5b67edc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.graphql-java-kickstart graphql-java-tools - 14.2.0-LOCAL + 13.1.2-SNAPSHOT jar GraphQL Java Tools From 5a6dca0d26002267fb27a776b2f04d40d0453b90 Mon Sep 17 00:00:00 2001 From: Oryan Date: Tue, 8 Oct 2024 11:22:25 -0400 Subject: [PATCH 18/23] Remove argline --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index b5b67edc..8e1c131b 100644 --- a/pom.xml +++ b/pom.xml @@ -307,8 +307,6 @@ **/*Test.* - - --add-reads kotlin.stdlib=kotlinx.coroutines.core From d59845f3b724388e70e4237f28b8df505b7ed530 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 15:25:45 +0000 Subject: [PATCH 19/23] Update all non-major dependencies --- pom.xml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/pom.xml b/pom.xml index 8e1c131b..9ce25cd2 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 11 2.0.20 1.9.0 - 2.17.0 + 2.18.0 22.3 1.0.4 @@ -63,31 +63,31 @@ com.fasterxml classmate - 1.6.0 + 1.7.0 org.slf4j slf4j-api - 2.0.9 + 2.0.16 org.apache.commons commons-lang3 - 3.14.0 + 3.17.0 org.javassist javassist - 3.29.2-GA + 3.30.2-GA provided org.springframework spring-aop - 5.3.31 + 5.3.39 provided @@ -100,7 +100,7 @@ ch.qos.logback logback-classic - 1.3.14 + 1.5.9 javax.servlet @@ -115,7 +115,7 @@ org.objenesis objenesis - 3.3 + 3.4 org.reactivestreams @@ -241,7 +241,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.4.0 + 3.6.0 add-test-source @@ -285,7 +285,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.11.0 + 3.13.0 11 11 @@ -295,12 +295,12 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.2 + 3.5.1 org.apache.maven.surefire surefire-junit4 - 3.2.2 + 3.5.1 @@ -312,7 +312,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + 3.4.2 test-jar @@ -327,7 +327,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.4.1 + 3.5.0 enforce @@ -345,7 +345,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 true ossrh @@ -364,7 +364,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 attach-sources @@ -378,7 +378,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.10.1 attach-javadocs @@ -391,7 +391,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.1.0 + 3.2.7 sign-artifacts From 10451fc2cedd5e0f74b5b8d518119a2513a72142 Mon Sep 17 00:00:00 2001 From: Oryan <73128417+oryan-block@users.noreply.github.com> Date: Tue, 8 Oct 2024 12:54:22 -0400 Subject: [PATCH 20/23] Update pom.xml --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ce25cd2..497b3e51 100644 --- a/pom.xml +++ b/pom.xml @@ -240,7 +240,6 @@ org.codehaus.mojo build-helper-maven-plugin - 3.6.0 From 400cf8203f975aae8693ca2f063d3a65d1d2ea6f Mon Sep 17 00:00:00 2001 From: Oryan Date: Tue, 8 Oct 2024 13:03:39 -0400 Subject: [PATCH 21/23] Bump version to 14.0.0 --- README.md | 8 ++++---- pom.xml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 26387007..cff15552 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,12 @@ Are you interested in improving our documentation, working on the codebase, revi ### Using Gradle Set the Kotlin version in your `gradle.properties`: ``` -kotlin.version=1.8.21 +kotlin.version=2.0.20 ``` Add the dependency: ```groovy -compile 'com.graphql-java-kickstart:graphql-java-tools:13.1.1' +compile 'com.graphql-java-kickstart:graphql-java-tools:14.0.0' ``` ### Using Maven @@ -34,7 +34,7 @@ Set the Kotlin version in your `` section: ```xml - 1.8.21 + 2.0.20 ``` @@ -43,7 +43,7 @@ Add the dependency: com.graphql-java-kickstart graphql-java-tools - 13.1.1 + 14.0.0 ``` diff --git a/pom.xml b/pom.xml index 497b3e51..7682c75e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.graphql-java-kickstart graphql-java-tools - 13.1.2-SNAPSHOT + 14.0.0-SNAPSHOT jar GraphQL Java Tools From 73d4f26a7b70daff3afd0fb84760591bed2198e3 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 8 Oct 2024 17:09:55 +0000 Subject: [PATCH 22/23] Update version for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7682c75e..495bed69 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.graphql-java-kickstart graphql-java-tools - 14.0.0-SNAPSHOT + 14.0.0 jar GraphQL Java Tools From a4eb31733d80b29478ecb2987fe1e4c501d0f3fa Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 8 Oct 2024 17:09:55 +0000 Subject: [PATCH 23/23] Update version for release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 495bed69..e97ec19a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.graphql-java-kickstart graphql-java-tools - 14.0.0 + 14.0.1-SNAPSHOT jar GraphQL Java Tools