graphql.kickstart.tools.util.Utils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of graphql-java-tools Show documentation
Show all versions of graphql-java-tools Show documentation
Tools to help map a GraphQL schema to existing Java objects.
package graphql.kickstart.tools.util
import graphql.kickstart.tools.GraphQLResolver
import graphql.kickstart.tools.SchemaParserOptions
import graphql.language.*
import graphql.schema.DataFetchingEnvironment
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import java.lang.reflect.Method
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Proxy
/**
* @author Andrew Potter
*/
internal typealias GraphQLRootResolver = GraphQLResolver
internal typealias JavaType = java.lang.reflect.Type
internal typealias JavaMethod = Method
internal typealias GraphQLLangType = Type<*>
internal fun Type<*>.unwrap(): Type<*> = when (this) {
is NonNullType -> this.type.unwrap()
is ListType -> this.type.unwrap()
else -> this
}
internal fun ObjectTypeDefinition.getExtendedFieldDefinitions(extensions: List): List {
return this.fieldDefinitions + extensions.filter { it.name == this.name }.flatMap { it.fieldDefinitions }
}
internal fun JavaType.unwrap(): Class =
if (this is ParameterizedType) {
this.rawType as Class<*>
} else {
this as Class<*>
}
internal fun DataFetchingEnvironment.coroutineScope(): CoroutineScope {
val context: Any? = this.getContext()
return if (context is CoroutineScope) context else CoroutineScope(Dispatchers.Default)
}
internal val Class<*>.declaredNonProxyMethods: List
get() {
return when {
Proxy.isProxyClass(this) -> emptyList()
else -> this.declaredMethods.toList()
}
}
internal fun getDocumentation(node: AbstractNode<*>, options: SchemaParserOptions): String? =
when {
node is AbstractDescribedNode<*> && node.description != null -> node.description.content
!options.useCommentsForDescriptions -> null
node.comments.isNullOrEmpty() -> null
else -> node.comments.asSequence()
.filter { !it.content.startsWith("#") }
.joinToString("\n") { it.content.trimEnd() }
.trimIndent()
}
/**
* Simple heuristic to check is 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) }