Skip to content

Commit b864c4b

Browse files
authored
Merge pull request #165 from guy120494/get-wrapped-dataFetcher
Expose Wrapped dataFetcher (fix #164)
2 parents 2e5d1df + 11d6702 commit b864c4b

File tree

1 file changed

+33
-22
lines changed

1 file changed

+33
-22
lines changed

src/main/kotlin/com/coxautodev/graphql/tools/MethodFieldResolver.kt

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ import java.util.*
1717
/**
1818
* @author Andrew Potter
1919
*/
20-
internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolverScanner.Search, options: SchemaParserOptions, val method: Method): FieldResolver(field, search, options, method.declaringClass) {
20+
internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolverScanner.Search, options: SchemaParserOptions, val method: Method) : FieldResolver(field, search, options, method.declaringClass) {
2121

2222
companion object {
2323
fun isBatched(method: Method, search: FieldResolverScanner.Search): Boolean {
24-
if(method.getAnnotation(Batched::class.java) != null) {
25-
if(!search.allowBatched) {
24+
if (method.getAnnotation(Batched::class.java) != null) {
25+
if (!search.allowBatched) {
2626
throw ResolverError("The @Batched annotation is only allowed on non-root resolver methods, but it was found on ${search.type.name}#${method.name}!")
2727
}
2828

@@ -41,8 +41,8 @@ internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolver
4141
val mapper = options.objectMapperProvider.provide(field)
4242

4343
// Add source argument if this is a resolver (but not a root resolver)
44-
if(this.search.requiredFirstParameterType != null) {
45-
val expectedType = if(batched) Iterable::class.java else this.search.requiredFirstParameterType
44+
if (this.search.requiredFirstParameterType != null) {
45+
val expectedType = if (batched) Iterable::class.java else this.search.requiredFirstParameterType
4646

4747
args.add { environment ->
4848
val source = environment.getSource<Any>()
@@ -57,23 +57,24 @@ internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolver
5757
// Add an argument for each argument defined in the GraphQL schema
5858
this.field.inputValueDefinitions.forEachIndexed { index, definition ->
5959

60-
val genericParameterType = this.getJavaMethodParameterType(index) ?: throw ResolverError("Missing method type at position ${this.getJavaMethodParameterIndex(index)}, this is most likely a bug with graphql-java-tools")
60+
val genericParameterType = this.getJavaMethodParameterType(index)
61+
?: throw ResolverError("Missing method type at position ${this.getJavaMethodParameterIndex(index)}, this is most likely a bug with graphql-java-tools")
6162

6263
val isNonNull = definition.type is NonNullType
6364
val isOptional = this.genericType.getRawClass(genericParameterType) == Optional::class.java
6465

65-
val typeReference = object: TypeReference<Any>() {
66+
val typeReference = object : TypeReference<Any>() {
6667
override fun getType() = genericParameterType
6768
}
6869

6970
args.add { environment ->
70-
val value = environment.arguments[definition.name] ?: if(isNonNull) {
71+
val value = environment.arguments[definition.name] ?: if (isNonNull) {
7172
throw ResolverError("Missing required argument with name '${definition.name}', this is most likely a bug with graphql-java-tools")
7273
} else {
7374
null
7475
}
7576

76-
if(value == null && isOptional) {
77+
if (value == null && isOptional) {
7778
return@add Optional.empty<Any>()
7879
}
7980

@@ -82,16 +83,16 @@ internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolver
8283
}
8384

8485
// Add DataFetchingEnvironment/Context argument
85-
if(this.additionalLastArgument) {
86+
if (this.additionalLastArgument) {
8687
val lastArgumentType = this.method.parameterTypes.last()
87-
when(lastArgumentType) {
88+
when (lastArgumentType) {
8889
null -> throw ResolverError("Expected at least one argument but got none, this is most likely a bug with graphql-java-tools")
8990
options.contextClass -> args.add { environment -> environment.getContext() }
9091
else -> args.add { environment -> environment }
9192
}
9293
}
9394

94-
return if(batched) {
95+
return if (batched) {
9596
BatchedMethodFieldResolverDataFetcher(getSourceResolver(), this.method, args, options)
9697
} else {
9798
MethodFieldResolverDataFetcher(getSourceResolver(), this.method, args, options)
@@ -107,14 +108,14 @@ internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolver
107108
} + listOf(returnValueMatch)
108109
}
109110

110-
private fun getIndexOffset() = if(resolverInfo is NormalResolverInfo) 1 else 0
111+
private fun getIndexOffset() = if (resolverInfo is NormalResolverInfo) 1 else 0
111112
private fun getJavaMethodParameterIndex(index: Int) = index + getIndexOffset()
112113

113114
private fun getJavaMethodParameterType(index: Int): JavaType? {
114115
val methodIndex = getJavaMethodParameterIndex(index)
115116
val parameters = method.parameterTypes
116117

117-
return if(parameters.size > methodIndex) {
118+
return if (parameters.size > methodIndex) {
118119
method.genericParameterTypes[getJavaMethodParameterIndex(index)]
119120
} else {
120121
null
@@ -124,14 +125,14 @@ internal class MethodFieldResolver(field: FieldDefinition, search: FieldResolver
124125
override fun toString() = "MethodFieldResolver{method=$method}"
125126
}
126127

127-
open class MethodFieldResolverDataFetcher(private val sourceResolver: SourceResolver, method: Method, private val args: List<ArgumentPlaceholder>, private val options: SchemaParserOptions): DataFetcher<Any> {
128+
open class MethodFieldResolverDataFetcher(private val sourceResolver: SourceResolver, method: Method, private val args: List<ArgumentPlaceholder>, private val options: SchemaParserOptions) : DataFetcher<Any> {
128129

129130
// Convert to reflactasm reflection
130131
private val methodAccess = MethodAccess.get(method.declaringClass)!!
131132
private val methodIndex = methodAccess.getIndex(method.name, *method.parameterTypes)
132133

133134
private class CompareGenericWrappers {
134-
companion object: Comparator<GenericWrapper> {
135+
companion object : Comparator<GenericWrapper> {
135136
override fun compare(w1: GenericWrapper, w2: GenericWrapper): Int = when {
136137
w1.type.isAssignableFrom(w2.type) -> 1
137138
else -> -1
@@ -147,21 +148,31 @@ open class MethodFieldResolverDataFetcher(private val sourceResolver: SourceReso
147148
result
148149
} else {
149150
val wrapper = options
150-
.genericWrappers
151-
.filter { it.type.isInstance(result) }
152-
.sortedWith(CompareGenericWrappers)
153-
.firstOrNull()
151+
.genericWrappers
152+
.filter { it.type.isInstance(result) }
153+
.sortedWith(CompareGenericWrappers)
154+
.firstOrNull()
154155
if (wrapper == null) {
155156
result
156157
} else {
157158
wrapper.transformer.invoke(result, environment)
158159
}
159160
}
160161
}
162+
163+
/**
164+
* Function that return the object used to fetch the data
165+
* It can be a DataFetcher or an entity
166+
*/
167+
@Suppress("unused")
168+
open fun getWrappedFetchingObject(environment: DataFetchingEnvironment): Any {
169+
return sourceResolver(environment)
170+
}
161171
}
162172

163-
class BatchedMethodFieldResolverDataFetcher(sourceResolver: SourceResolver, method: Method, args: List<ArgumentPlaceholder>, options: SchemaParserOptions): MethodFieldResolverDataFetcher(sourceResolver, method, args, options) {
164-
@Batched override fun get(environment: DataFetchingEnvironment) = super.get(environment)
173+
class BatchedMethodFieldResolverDataFetcher(sourceResolver: SourceResolver, method: Method, args: List<ArgumentPlaceholder>, options: SchemaParserOptions) : MethodFieldResolverDataFetcher(sourceResolver, method, args, options) {
174+
@Batched
175+
override fun get(environment: DataFetchingEnvironment) = super.get(environment)
165176
}
166177

167178
internal typealias ArgumentPlaceholder = (DataFetchingEnvironment) -> Any?

0 commit comments

Comments
 (0)