Skip to content

Commit 16f0977

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 35f35ff + b4b2627 commit 16f0977

File tree

6 files changed

+30
-7
lines changed

6 files changed

+30
-7
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Take a look at our new [documentation](https://www.graphql-java-kickstart.com/to
4141

4242
* **Schema First**: GraphQL Java Tools allows you to write your schema in a simple, portable way using the [GraphQL schema language](http://graphql.org/learn/schema/) instead of hard-to-read builders in code.
4343
* **Minimal Boilerplate**: It takes a lot of work to describe your GraphQL-Java objects manually, and quickly becomes unreadable.
44-
A few libraries exist to ease the boilerplate pain, including [GraphQL-Java's built-in schema-first wiring](http://graphql-java.readthedocs.io/en/latest/schema.html), but none (so far) do type and datafetcher discovery.
44+
A few libraries exist to ease the boilerplate pain, including [GraphQL-Java's built-in schema-first wiring](https://www.graphql-java.com/documentation/master/schema/), but none (so far) do type and datafetcher discovery.
4545
* **Stateful Data Fetchers**: If you're using an IOC container (like Spring), it's hard to wire up datafetchers that make use of beans you've already defined without a bunch of fragile configuration. GraphQL Java Tools allows you to register "Resolvers" for any type that can bring state along and use that to resolve fields.
4646
* **Generated DataFetchers**: GraphQL Java Tools automatically creates data fetchers for your fields that call the appropriate method on your java class. This means all you have to do to create a new field is add the field definition to your schema and add a corresponding method on your class.
4747
* **Type->Class Discovery**: GraphQL Java Tools starts from your root objects (Query, Mutation) and, as it's generating data fetchers for you, starts to learn about the classes you use for a certain GraphQL type.

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@
5050
<artifactId>graphql-java</artifactId>
5151
<version>11.0</version>
5252
</dependency>
53+
<dependency>
54+
<groupId>com.fasterxml</groupId>
55+
<artifactId>classmate</artifactId>
56+
<version>1.4.0</version>
57+
</dependency>
5358
<dependency>
5459
<groupId>com.fasterxml.jackson.core</groupId>
5560
<artifactId>jackson-core</artifactId>

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.coxautodev.graphql.tools
22

3+
import com.fasterxml.classmate.ResolvedType
34
import com.google.common.primitives.Primitives
45
import org.apache.commons.lang3.reflect.TypeUtils
56
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
@@ -131,6 +132,14 @@ internal open class GenericType(protected val mostSpecificType: JavaType, protec
131132
val actualTypeArguments = type.actualTypeArguments.map { replaceTypeVariable(it) }.toTypedArray()
132133
ParameterizedTypeImpl.make(type.rawType as Class<*>?, actualTypeArguments, type.ownerType)
133134
}
135+
is ResolvedType -> {
136+
if (type.typeParameters.isEmpty()) {
137+
type.erasedType
138+
} else {
139+
val actualTypeArguments = type.typeParameters.map { replaceTypeVariable(it) }.toTypedArray()
140+
ParameterizedTypeImpl.make(type.erasedType, actualTypeArguments, null)
141+
}
142+
}
134143
is TypeVariable<*> -> {
135144
if (declaringType is ParameterizedType) {
136145
TypeUtils.getRawType(type, declaringType)

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.coxautodev.graphql.tools
22

3+
import com.fasterxml.classmate.TypeResolver
34
import graphql.language.FieldDefinition
45
import graphql.schema.DataFetcher
56
import graphql.schema.DataFetchingEnvironment
6-
import java.lang.reflect.ParameterizedType
77

88
/**
99
* @author Nick Weedon
@@ -14,12 +14,17 @@ internal class PropertyMapResolver(field: FieldDefinition, search: FieldResolver
1414

1515
var mapGenericValue : JavaType = getMapGenericType(relativeTo)
1616

17+
/**
18+
* Takes a type which implements Map and tries to find the
19+
* value type of that map. For some reason, mapClass is losing
20+
* its generics somewhere along the way and is always a raw
21+
* type
22+
*/
1723
fun getMapGenericType(mapClass : JavaType) : JavaType {
18-
if(mapClass is ParameterizedType) {
19-
return mapClass.actualTypeArguments[1]
20-
} else {
21-
return Object::class.java
22-
}
24+
val resolvedType = TypeResolver().resolve(mapClass)
25+
26+
val typeParameters = resolvedType.typeParametersFor(Map::class.java)
27+
return typeParameters.elementAtOrElse(1) { Object::class.java }
2328
}
2429

2530
override fun createDataFetcher(): DataFetcher<*> {

src/main/kotlin/com/coxautodev/graphql/tools/relay/RelayConnectionFactory.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ class RelayConnectionFactory : TypeDefinitionFactory {
7171
.name("PageInfo")
7272
.fieldDefinition(FieldDefinition("hasPreviousPage", NonNullType(TypeName("Boolean"))))
7373
.fieldDefinition(FieldDefinition("hasNextPage", NonNullType(TypeName("Boolean"))))
74+
.fieldDefinition(FieldDefinition("startCursor", TypeName("String")))
75+
.fieldDefinition(FieldDefinition("endCursor", TypeName("String")))
7476
.build()
7577

7678
private fun Directive.forTypeName(): String {

src/test/java/com/coxautodev/graphql/tools/RelayConnectionTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public String call() {
4444
" pageInfo {\n" +
4545
" hasPreviousPage,\n" +
4646
" hasNextPage\n" +
47+
" startCursor\n" +
48+
" endCursor\n" +
4749
" }\n" +
4850
" }\n" +
4951
"}";

0 commit comments

Comments
 (0)