@@ -23,9 +23,12 @@ import graphql.language.TypeDefinition
23
23
import graphql.language.TypeName
24
24
import graphql.language.UnionTypeDefinition
25
25
import graphql.language.Value
26
+ import graphql.schema.GraphQLArgument
26
27
import graphql.schema.GraphQLDirective
27
28
import graphql.schema.GraphQLEnumType
29
+ import graphql.schema.GraphQLEnumValueDefinition
28
30
import graphql.schema.GraphQLFieldDefinition
31
+ import graphql.schema.GraphQLInputObjectField
29
32
import graphql.schema.GraphQLInputObjectType
30
33
import graphql.schema.GraphQLInputType
31
34
import graphql.schema.GraphQLInterfaceType
@@ -42,8 +45,7 @@ import graphql.schema.idl.DirectiveBehavior
42
45
import graphql.schema.idl.RuntimeWiring
43
46
import graphql.schema.idl.ScalarInfo
44
47
import graphql.schema.idl.SchemaGeneratorHelper
45
- import java.util.ArrayList
46
- import java.util.HashSet
48
+ import java.util.*
47
49
import kotlin.reflect.KClass
48
50
49
51
/* *
@@ -56,9 +58,11 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
56
58
companion object {
57
59
const val DEFAULT_DEPRECATION_MESSAGE = " No longer supported"
58
60
59
- @JvmStatic fun newParser () = SchemaParserBuilder ()
61
+ @JvmStatic
62
+ fun newParser () = SchemaParserBuilder ()
63
+
60
64
internal fun getDocumentation (node : AbstractNode <* >): String? = node.comments?.asSequence()
61
- ?.filter {! it.content.startsWith(" #" )}
65
+ ?.filter { ! it.content.startsWith(" #" ) }
62
66
?.joinToString(" \n " ) { it.content.trimEnd() }
63
67
?.trimIndent()
64
68
}
@@ -110,9 +114,12 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
110
114
val mutationName = rootInfo.getMutationName()
111
115
val subscriptionName = rootInfo.getSubscriptionName()
112
116
113
- val query = objects.find { it.name == queryName } ? : throw SchemaError (" Expected a Query object with name '$queryName ' but found none!" )
114
- val mutation = objects.find { it.name == mutationName } ? : if (rootInfo.isMutationRequired()) throw SchemaError (" Expected a Mutation object with name '$mutationName ' but found none!" ) else null
115
- val subscription = objects.find { it.name == subscriptionName } ? : if (rootInfo.isSubscriptionRequired()) throw SchemaError (" Expected a Subscription object with name '$subscriptionName ' but found none!" ) else null
117
+ val query = objects.find { it.name == queryName }
118
+ ? : throw SchemaError (" Expected a Query object with name '$queryName ' but found none!" )
119
+ val mutation = objects.find { it.name == mutationName }
120
+ ? : if (rootInfo.isMutationRequired()) throw SchemaError (" Expected a Mutation object with name '$mutationName ' but found none!" ) else null
121
+ val subscription = objects.find { it.name == subscriptionName }
122
+ ? : if (rootInfo.isSubscriptionRequired()) throw SchemaError (" Expected a Subscription object with name '$subscriptionName ' but found none!" ) else null
116
123
117
124
return SchemaObjects (query, mutation, subscription, (objects + inputObjects + enums + interfaces + unions).toSet())
118
125
}
@@ -130,22 +137,24 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
130
137
private fun createObject (definition : ObjectTypeDefinition , interfaces : List <GraphQLInterfaceType >): GraphQLObjectType {
131
138
val name = definition.name
132
139
val builder = GraphQLObjectType .newObject()
133
- .name(name)
134
- .definition(definition)
135
- .description(getDocumentation(definition))
140
+ .name(name)
141
+ .definition(definition)
142
+ .description(getDocumentation(definition))
136
143
137
144
builder.withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .OBJECT ))
138
145
139
146
definition.implements.forEach { implementsDefinition ->
140
147
val interfaceName = (implementsDefinition as TypeName ).name
141
- builder.withInterface(interfaces.find { it.name == interfaceName } ? : throw SchemaError (" Expected interface type with name '$interfaceName ' but found none!" ))
148
+ builder.withInterface(interfaces.find { it.name == interfaceName }
149
+ ? : throw SchemaError (" Expected interface type with name '$interfaceName ' but found none!" ))
142
150
}
143
151
144
152
definition.getExtendedFieldDefinitions(extensionDefinitions).forEach { fieldDefinition ->
145
153
fieldDefinition.description
146
154
builder.field { field ->
147
155
createField(field, fieldDefinition)
148
- field.dataFetcher(fieldResolversByType[definition]?.get(fieldDefinition)?.createDataFetcher() ? : throw SchemaError (" No resolver method found for object type '${definition.name} ' and field '${fieldDefinition.name} ', this is most likely a bug with graphql-java-tools" ))
156
+ field.dataFetcher(fieldResolversByType[definition]?.get(fieldDefinition)?.createDataFetcher()
157
+ ? : throw SchemaError (" No resolver method found for object type '${definition.name} ' and field '${fieldDefinition.name} ', this is most likely a bug with graphql-java-tools" ))
149
158
150
159
val wiredField = directiveGenerator.onField(field.build(), DirectiveBehavior .Params (runtimeWiring))
151
160
GraphQLFieldDefinition .Builder (wiredField)
@@ -172,21 +181,21 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
172
181
173
182
private fun createInputObject (definition : InputObjectTypeDefinition ): GraphQLInputObjectType {
174
183
val builder = GraphQLInputObjectType .newInputObject()
175
- .name(definition.name)
176
- .definition(definition)
177
- .description(getDocumentation(definition))
184
+ .name(definition.name)
185
+ .definition(definition)
186
+ .description(getDocumentation(definition))
178
187
179
188
builder.withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .INPUT_OBJECT ))
180
189
181
190
definition.inputValueDefinitions.forEach { inputDefinition ->
182
- builder.field { field ->
183
- field .name(inputDefinition.name)
184
- field .definition(inputDefinition)
185
- field .description(getDocumentation(inputDefinition))
186
- field .defaultValue(inputDefinition.defaultValue)
187
- field .type(determineInputType(inputDefinition.type))
188
- field .withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .INPUT_FIELD_DEFINITION ))
189
- }
191
+ val fieldBuilder = GraphQLInputObjectField .newInputObjectField()
192
+ .name(inputDefinition.name)
193
+ .definition(inputDefinition)
194
+ .description(getDocumentation(inputDefinition))
195
+ .defaultValue(inputDefinition.defaultValue)
196
+ .type(determineInputType(inputDefinition.type))
197
+ .withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .INPUT_FIELD_DEFINITION ))
198
+ builder.field(directiveGenerator.onInputObjectField(fieldBuilder.build(), DirectiveBehavior . Params (runtimeWiring)))
190
199
}
191
200
192
201
return directiveGenerator.onInputObject(builder.build(), DirectiveBehavior .Params (runtimeWiring))
@@ -198,20 +207,20 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
198
207
if (! type.unwrap().isEnum) throw SchemaError (" Type '$name ' is declared as an enum in the GraphQL schema but is not a Java enum!" )
199
208
200
209
val builder = GraphQLEnumType .newEnum()
201
- .name(name)
202
- .definition(definition)
203
- .description(getDocumentation(definition))
210
+ .name(name)
211
+ .definition(definition)
212
+ .description(getDocumentation(definition))
204
213
205
214
builder.withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .ENUM ))
206
215
207
216
definition.enumValueDefinitions.forEach { enumDefinition ->
208
217
val enumName = enumDefinition.name
209
- val enumValue = type.unwrap().enumConstants.find { (it as Enum <* >).name == enumName } ? : throw SchemaError (" Expected value for name '$enumName ' in enum '${type.unwrap().simpleName} ' but found none!" )
218
+ val enumValue = type.unwrap().enumConstants.find { (it as Enum <* >).name == enumName }
219
+ ? : throw SchemaError (" Expected value for name '$enumName ' in enum '${type.unwrap().simpleName} ' but found none!" )
220
+ val enumValueDirectives = buildDirectives(enumDefinition.directives, setOf (), Introspection .DirectiveLocation .ENUM_VALUE ).toMutableList()
210
221
getDeprecated(enumDefinition.directives).let {
211
- when (it) {
212
- is String -> builder.value(enumName, enumValue, getDocumentation(enumDefinition), it)
213
- else -> builder.value(enumName, enumValue, getDocumentation(enumDefinition))
214
- }
222
+ val enumValueDefinition = GraphQLEnumValueDefinition (enumName, getDocumentation(enumDefinition), enumValue, it, enumValueDirectives)
223
+ builder.value(directiveGenerator.onEnumValue(enumValueDefinition, DirectiveBehavior .Params (runtimeWiring)))
215
224
}
216
225
}
217
226
@@ -221,10 +230,10 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
221
230
private fun createInterfaceObject (definition : InterfaceTypeDefinition ): GraphQLInterfaceType {
222
231
val name = definition.name
223
232
val builder = GraphQLInterfaceType .newInterface()
224
- .name(name)
225
- .definition(definition)
226
- .description(getDocumentation(definition))
227
- .typeResolver(TypeResolverProxy ())
233
+ .name(name)
234
+ .definition(definition)
235
+ .description(getDocumentation(definition))
236
+ .typeResolver(TypeResolverProxy ())
228
237
229
238
builder.withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .INTERFACE ))
230
239
@@ -238,10 +247,10 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
238
247
private fun createUnionObject (definition : UnionTypeDefinition , types : List <GraphQLObjectType >): GraphQLUnionType {
239
248
val name = definition.name
240
249
val builder = GraphQLUnionType .newUnionType()
241
- .name(name)
242
- .definition(definition)
243
- .description(getDocumentation(definition))
244
- .typeResolver(TypeResolverProxy ())
250
+ .name(name)
251
+ .definition(definition)
252
+ .description(getDocumentation(definition))
253
+ .typeResolver(TypeResolverProxy ())
245
254
246
255
builder.withDirectives(* buildDirectives(definition.directives, setOf (), Introspection .DirectiveLocation .UNION ))
247
256
@@ -257,40 +266,40 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
257
266
val typeName = (it as TypeName ).name
258
267
259
268
// Is this a nested union? If so, expand
260
- val nestedUnion : UnionTypeDefinition ? = unionDefinitions.find { otherDefinition -> typeName == otherDefinition.name }
269
+ val nestedUnion: UnionTypeDefinition ? = unionDefinitions.find { otherDefinition -> typeName == otherDefinition.name }
261
270
262
271
if (nestedUnion != null ) {
263
272
leafObjects.addAll(getLeafUnionObjects(nestedUnion, types))
264
273
} else {
265
- leafObjects.add(types.find { it.name == typeName } ? : throw SchemaError (" Expected object type '$typeName ' for union type '$name ', but found none!" ))
274
+ leafObjects.add(types.find { it.name == typeName }
275
+ ? : throw SchemaError (" Expected object type '$typeName ' for union type '$name ', but found none!" ))
266
276
}
267
277
}
268
278
return leafObjects
269
279
}
270
280
271
- private fun createField (field : GraphQLFieldDefinition .Builder , fieldDefinition : FieldDefinition ): GraphQLFieldDefinition .Builder {
281
+ private fun createField (field : GraphQLFieldDefinition .Builder , fieldDefinition : FieldDefinition ): GraphQLFieldDefinition .Builder {
272
282
field.name(fieldDefinition.name)
273
283
field.description(getDocumentation(fieldDefinition))
274
284
field.definition(fieldDefinition)
275
285
getDeprecated(fieldDefinition.directives)?.let { field.deprecate(it) }
276
286
field.type(determineOutputType(fieldDefinition.type))
277
287
fieldDefinition.inputValueDefinitions.forEach { argumentDefinition ->
278
- field.argument { argument ->
279
- argument.name(argumentDefinition.name)
280
- argument.definition(argumentDefinition)
281
- argument.description(getDocumentation(argumentDefinition))
282
- argument.defaultValue(buildDefaultValue(argumentDefinition.defaultValue))
283
- argument.type(determineInputType(argumentDefinition.type))
284
- argument.withDirectives(* buildDirectives(argumentDefinition.directives, setOf (), Introspection .DirectiveLocation .ARGUMENT_DEFINITION ))
285
-
286
- }
288
+ val argumentBuilder = GraphQLArgument .newArgument()
289
+ .name(argumentDefinition.name)
290
+ .definition(argumentDefinition)
291
+ .description(getDocumentation(argumentDefinition))
292
+ .defaultValue(buildDefaultValue(argumentDefinition.defaultValue))
293
+ .type(determineInputType(argumentDefinition.type))
294
+ .withDirectives(* buildDirectives(argumentDefinition.directives, setOf (), Introspection .DirectiveLocation .ARGUMENT_DEFINITION ))
295
+ field.argument(directiveGenerator.onArgument(argumentBuilder.build(), DirectiveBehavior .Params (runtimeWiring)))
287
296
}
288
297
field.withDirectives(* buildDirectives(fieldDefinition.directives, setOf (), Introspection .DirectiveLocation .FIELD_DEFINITION ))
289
298
return field
290
299
}
291
300
292
301
private fun buildDefaultValue (value : Value <* >? ): Any? {
293
- return when (value) {
302
+ return when (value) {
294
303
null -> null
295
304
is IntValue -> value.value
296
305
is FloatValue -> value.value
@@ -305,10 +314,11 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
305
314
306
315
private fun determineOutputType (typeDefinition : Type <* >) =
307
316
determineType(GraphQLOutputType ::class , typeDefinition, permittedTypesForObject) as GraphQLOutputType
317
+
308
318
private fun determineInputType (typeDefinition : Type <* >) =
309
319
determineType(GraphQLInputType ::class , typeDefinition, permittedTypesForInputObject) as GraphQLInputType
310
320
311
- private fun <T : Any > determineType (expectedType : KClass <T >, typeDefinition : Type <* >, allowedTypeReferences : Set <String >): GraphQLType =
321
+ private fun <T : Any > determineType (expectedType : KClass <T >, typeDefinition : Type <* >, allowedTypeReferences : Set <String >): GraphQLType =
312
322
when (typeDefinition) {
313
323
is ListType -> GraphQLList (determineType(expectedType, typeDefinition.type, allowedTypeReferences))
314
324
is NonNullType -> GraphQLNonNull (determineType(expectedType, typeDefinition.type, allowedTypeReferences))
@@ -335,10 +345,10 @@ class SchemaParser internal constructor(scanResult: ScannedSchemaObjects, privat
335
345
* indicating no deprecation directive was found within the directives list.
336
346
*/
337
347
private fun getDeprecated (directives : List <Directive >): String? =
338
- getDirective(directives, " deprecated" )?.let { directive ->
339
- (directive.arguments.find { it.name == " reason" }?.value as ? StringValue )?.value ? :
340
- DEFAULT_DEPRECATION_MESSAGE
341
- }
348
+ getDirective(directives, " deprecated" )?.let { directive ->
349
+ (directive.arguments.find { it.name == " reason" }?.value as ? StringValue )?.value
350
+ ? : DEFAULT_DEPRECATION_MESSAGE
351
+ }
342
352
343
353
private fun getDirective (directives : List <Directive >, name : String ): Directive ? = directives.find {
344
354
it.name == name
0 commit comments