2222import graphql .language .Type ;
2323import graphql .language .TypeDefinition ;
2424import graphql .language .TypeExtensionDefinition ;
25- import graphql .language .TypeName ;
2625import graphql .language .UnionTypeDefinition ;
2726import graphql .language .Value ;
2827import graphql .schema .DataFetcher ;
4241import graphql .schema .PropertyDataFetcher ;
4342import graphql .schema .TypeResolver ;
4443import graphql .schema .TypeResolverProxy ;
44+ import graphql .schema .idl .errors .NotAnInputTypeError ;
45+ import graphql .schema .idl .errors .NotAnOutputTypeError ;
4546import graphql .schema .idl .errors .SchemaProblem ;
4647
4748import java .util .Collections ;
5354import java .util .Stack ;
5455
5556/**
56- * This can generate a working runtime schema from a compiled type registry and runtime wiring
57+ * This can generate a working runtime schema from a type registry and runtime wiring
5758 */
5859public class SchemaGenerator {
5960
@@ -133,7 +134,7 @@ public SchemaGenerator() {
133134 /**
134135 * This will take a {@link TypeDefinitionRegistry} and a {@link RuntimeWiring} and put them together to create a executable schema
135136 *
136- * @param typeRegistry this can be obtained via {@link SchemaCompiler#compile (String)}
137+ * @param typeRegistry this can be obtained via {@link SchemaParser#parse (String)}
137138 * @param wiring this can be built using {@link RuntimeWiring#newRuntimeWiring()}
138139 * @return an executable schema
139140 * @throws SchemaProblem if there are problems in assembling a schema such as missing type resolvers or no operations defined
@@ -157,9 +158,11 @@ private GraphQLSchema makeExecutableSchemaImpl(BuildContext buildCtx) {
157158 @ SuppressWarnings ("OptionalGetWithoutIsPresent" )
158159 OperationTypeDefinition queryOp = operationTypes .stream ().filter (op -> "query" .equals (op .getName ())).findFirst ().get ();
159160 Optional <OperationTypeDefinition > mutationOp = operationTypes .stream ().filter (op -> "mutation" .equals (op .getName ())).findFirst ();
161+ Optional <OperationTypeDefinition > subscriptionOp = operationTypes .stream ().filter (op -> "subscription" .equals (op .getName ())).findFirst ();
160162
161163 GraphQLObjectType query = buildOperation (buildCtx , queryOp );
162164 GraphQLObjectType mutation ;
165+ GraphQLObjectType subscription ;
163166
164167 GraphQLSchema .Builder schemaBuilder = GraphQLSchema
165168 .newSchema ()
@@ -169,6 +172,10 @@ private GraphQLSchema makeExecutableSchemaImpl(BuildContext buildCtx) {
169172 mutation = buildOperation (buildCtx , mutationOp .get ());
170173 schemaBuilder .mutation (mutation );
171174 }
175+ if (subscriptionOp .isPresent ()) {
176+ subscription = buildOperation (buildCtx , subscriptionOp .get ());
177+ schemaBuilder .subscription (subscription );
178+ }
172179 return schemaBuilder .build ();
173180 }
174181
@@ -213,8 +220,11 @@ private <T extends GraphQLOutputType> T buildOutputType(BuildContext buildCtx, T
213220 outputType = buildUnionType (buildCtx , (UnionTypeDefinition ) typeDefinition );
214221 } else if (typeDefinition instanceof EnumTypeDefinition ) {
215222 outputType = buildEnumType ((EnumTypeDefinition ) typeDefinition );
216- } else {
223+ } else if ( typeDefinition instanceof ScalarTypeDefinition ) {
217224 outputType = buildScalar (buildCtx , (ScalarTypeDefinition ) typeDefinition );
225+ } else {
226+ // typeDefinition is not a valid output type
227+ throw new NotAnOutputTypeError (typeDefinition );
218228 }
219229
220230 buildCtx .put (outputType );
@@ -243,8 +253,11 @@ private GraphQLInputType buildInputType(BuildContext buildCtx, Type rawType) {
243253 inputType = buildInputObjectType (buildCtx , (InputObjectTypeDefinition ) typeDefinition );
244254 } else if (typeDefinition instanceof EnumTypeDefinition ) {
245255 inputType = buildEnumType ((EnumTypeDefinition ) typeDefinition );
246- } else {
256+ } else if ( typeDefinition instanceof ScalarTypeDefinition ) {
247257 inputType = buildScalar (buildCtx , (ScalarTypeDefinition ) typeDefinition );
258+ } else {
259+ // typeDefinition is not a valid InputType
260+ throw new NotAnInputTypeError (typeDefinition );
248261 }
249262
250263 buildCtx .put (inputType );
@@ -253,6 +266,7 @@ private GraphQLInputType buildInputType(BuildContext buildCtx, Type rawType) {
253266 }
254267
255268 private GraphQLObjectType buildObjectType (BuildContext buildCtx , ObjectTypeDefinition typeDefinition ) {
269+
256270 GraphQLObjectType .Builder builder = GraphQLObjectType .newObject ();
257271 builder .name (typeDefinition .getName ());
258272 builder .description (buildDescription (typeDefinition ));
@@ -331,7 +345,8 @@ private GraphQLUnionType buildUnionType(BuildContext buildCtx, UnionTypeDefiniti
331345 builder .typeResolver (getTypeResolver (buildCtx , typeDefinition .getName ()));
332346
333347 typeDefinition .getMemberTypes ().forEach (mt -> {
334- builder .possibleType (new GraphQLTypeReference (((TypeName ) mt ).getName ()));
348+ GraphQLObjectType objectType = buildOutputType (buildCtx , mt );
349+ builder .possibleType (objectType );
335350 });
336351 return builder .build ();
337352 }
@@ -460,4 +475,4 @@ private String buildDescription(Node node) {
460475 }
461476 return sb .toString ();
462477 }
463- }
478+ }
0 commit comments