@@ -98,13 +98,15 @@ public final class SchemaMappingInspector {
98
98
99
99
private SchemaMappingInspector (
100
100
GraphQLSchema schema , Map <String , Map <String , DataFetcher >> dataFetchers ,
101
- List < ClassResolver > classResolvers , Function < GraphQLObjectType , String > classNameFunction ) {
101
+ InterfaceUnionLookup interfaceUnionLookup ) {
102
102
103
103
Assert .notNull (schema , "GraphQLSchema is required" );
104
104
Assert .notNull (dataFetchers , "DataFetcher map is required" );
105
+ Assert .notNull (interfaceUnionLookup , "InterfaceUnionLookup is required" );
106
+
105
107
this .schema = schema ;
106
108
this .dataFetchers = dataFetchers ;
107
- this .interfaceUnionLookup = new InterfaceUnionLookup ( schema , dataFetchers , classResolvers , classNameFunction ) ;
109
+ this .interfaceUnionLookup = interfaceUnionLookup ;
108
110
}
109
111
110
112
@@ -374,16 +376,12 @@ static ClassResolver create(Map<Class<?>, String> mappings) {
374
376
/**
375
377
* Default implementation of {@link Initializer}.
376
378
*/
377
- private static class DefaultInitializer implements Initializer {
379
+ private static final class DefaultInitializer implements Initializer {
378
380
379
381
private Function <GraphQLObjectType , String > classNameFunction = GraphQLObjectType ::getName ;
380
382
381
383
private final List <ClassResolver > classResolvers = new ArrayList <>();
382
384
383
- DefaultInitializer () {
384
- this .classResolvers .add ((objectType , interfaceOrUnionType ) -> Collections .emptyList ());
385
- }
386
-
387
385
@ Override
388
386
public Initializer classNameFunction (Function <GraphQLObjectType , String > function ) {
389
387
this .classNameFunction = function ;
@@ -398,8 +396,17 @@ public Initializer classResolver(ClassResolver resolver) {
398
396
399
397
@ Override
400
398
public SchemaReport inspect (GraphQLSchema schema , Map <String , Map <String , DataFetcher >> fetchers ) {
401
- return new SchemaMappingInspector (
402
- schema , fetchers , this .classResolvers , this .classNameFunction ).getOrCreateReport ();
399
+
400
+ ReflectionClassResolver reflectionResolver =
401
+ ReflectionClassResolver .create (schema , fetchers , this .classNameFunction );
402
+
403
+ List <ClassResolver > resolvers = new ArrayList <>(this .classResolvers );
404
+ resolvers .add (reflectionResolver );
405
+
406
+ InterfaceUnionLookup lookup = InterfaceUnionLookup .create (schema , resolvers );
407
+
408
+ SchemaMappingInspector inspector = new SchemaMappingInspector (schema , fetchers , lookup );
409
+ return inspector .getOrCreateReport ();
403
410
}
404
411
}
405
412
@@ -427,18 +434,19 @@ public List<Class<?>> resolveClass(GraphQLObjectType objectType, GraphQLNamedOut
427
434
* the GraphQL object type, and then prepends a prefixes such as a package
428
435
* name and/or an outer class name.
429
436
*/
430
- private static class ReflectionClassResolver implements ClassResolver {
437
+ private static final class ReflectionClassResolver implements ClassResolver {
438
+
439
+ private static final Predicate <String > PACKAGE_PREDICATE = (name ) -> !name .startsWith ("java." );
431
440
432
441
private final Function <GraphQLObjectType , String > classNameFunction ;
433
442
434
- private final MultiValueMap <String , String > classPrefixes = new LinkedMultiValueMap <>() ;
443
+ private final MultiValueMap <String , String > classPrefixes ;
435
444
436
- ReflectionClassResolver (Function <GraphQLObjectType , String > classNameFunction ) {
437
- this .classNameFunction = classNameFunction ;
438
- }
445
+ private ReflectionClassResolver (
446
+ Function <GraphQLObjectType , String > nameFunction , MultiValueMap <String , String > prefixes ) {
439
447
440
- void addClassPrefix ( String interfaceOrUnionTypeName , String classPrefix ) {
441
- this .classPrefixes . add ( interfaceOrUnionTypeName , classPrefix ) ;
448
+ this . classNameFunction = nameFunction ;
449
+ this .classPrefixes = prefixes ;
442
450
}
443
451
444
452
@ Override
@@ -455,49 +463,16 @@ public List<Class<?>> resolveClass(GraphQLObjectType objectType, GraphQLNamedOut
455
463
}
456
464
return Collections .emptyList ();
457
465
}
458
- }
459
-
460
-
461
- /**
462
- * Provides methods to look up GraphQL Object and Java type pairs associated
463
- * with GraphQL interface and union types.
464
- */
465
- private static class InterfaceUnionLookup {
466
-
467
- private static final Predicate <String > PACKAGE_PREDICATE = (name ) -> !name .startsWith ("java." );
468
-
469
- private static final LinkedMultiValueMap <GraphQLType , ResolvableType > EMPTY_MULTI_VALUE_MAP = new LinkedMultiValueMap <>(0 );
470
-
471
- /** Interface or union type name to implementing or member GraphQL-Java types pairs. */
472
- private final Map <String , MultiValueMap <GraphQLType , ResolvableType >> mappings = new LinkedHashMap <>();
473
-
474
- InterfaceUnionLookup (
475
- GraphQLSchema schema , Map <String , Map <String , DataFetcher >> dataFetchers ,
476
- List <ClassResolver > classResolvers , Function <GraphQLObjectType , String > classNameFunction ) {
477
-
478
- addReflectionClassResolver (schema , dataFetchers , classNameFunction , classResolvers );
479
-
480
- for (GraphQLNamedType type : schema .getAllTypesAsList ()) {
481
- if (type instanceof GraphQLUnionType union ) {
482
- for (GraphQLNamedOutputType member : union .getTypes ()) {
483
- addTypeMapping (union , (GraphQLObjectType ) member , classResolvers );
484
- }
485
- }
486
- else if (type instanceof GraphQLObjectType objectType ) {
487
- for (GraphQLNamedOutputType interfaceType : objectType .getInterfaces ()) {
488
- addTypeMapping (interfaceType , objectType , classResolvers );
489
- }
490
- }
491
- }
492
- }
493
466
494
- private static void addReflectionClassResolver (
467
+ /**
468
+ * Create a resolver that is aware of packages associated with controller
469
+ * methods mapped to unions and interfaces.
470
+ */
471
+ public static ReflectionClassResolver create (
495
472
GraphQLSchema schema , Map <String , Map <String , DataFetcher >> dataFetchers ,
496
- Function <GraphQLObjectType , String > classNameFunction , List <ClassResolver > classResolvers ) {
497
-
498
- ReflectionClassResolver resolver = new ReflectionClassResolver (classNameFunction );
499
- classResolvers .add (resolver );
473
+ Function <GraphQLObjectType , String > classNameFunction ) {
500
474
475
+ MultiValueMap <String , String > classPrefixes = new LinkedMultiValueMap <>();
501
476
for (Map .Entry <String , Map <String , DataFetcher >> typeEntry : dataFetchers .entrySet ()) {
502
477
String typeName = typeEntry .getKey ();
503
478
GraphQLType parentType = schema .getType (typeName );
@@ -517,45 +492,36 @@ private static void addReflectionClassResolver(
517
492
Class <?> clazz = pair .resolvableType ().resolve (Object .class );
518
493
if (PACKAGE_PREDICATE .test (clazz .getPackageName ())) {
519
494
int index = clazz .getName ().indexOf (clazz .getSimpleName ());
520
- resolver . addClassPrefix (outputTypeName , clazz .getName ().substring (0 , index ));
495
+ classPrefixes . add (outputTypeName , clazz .getName ().substring (0 , index ));
521
496
}
522
497
else if (fieldEntry .getValue () instanceof SelfDescribingDataFetcher <?> sddf ) {
523
498
if (sddf .getReturnType ().getSource () instanceof MethodParameter param ) {
524
499
clazz = param .getDeclaringClass ();
525
500
int index = clazz .getName ().indexOf (clazz .getSimpleName ());
526
- resolver . addClassPrefix (outputTypeName , clazz .getName ().substring (0 , index ));
501
+ classPrefixes . add (outputTypeName , clazz .getName ().substring (0 , index ));
527
502
}
528
503
}
529
504
}
530
505
}
531
506
}
507
+ return new ReflectionClassResolver (classNameFunction , classPrefixes );
532
508
}
509
+ }
533
510
534
- private void addTypeMapping (
535
- GraphQLNamedOutputType interfaceOrUnionType , GraphQLObjectType objectType ,
536
- List <ClassResolver > classResolvers ) {
537
511
538
- List <ResolvableType > resolvableTypes = new ArrayList <>();
512
+ /**
513
+ * Lookup for GraphQL Object and Java type pairs that are associated with
514
+ * GraphQL union and interface types.
515
+ */
516
+ private static final class InterfaceUnionLookup {
539
517
540
- for (ClassResolver resolver : classResolvers ) {
541
- List <Class <?>> classes = resolver .resolveClass (objectType , interfaceOrUnionType );
542
- if (!classes .isEmpty ()) {
543
- for (Class <?> clazz : classes ) {
544
- ResolvableType resolvableType = ResolvableType .forClass (clazz );
545
- resolvableTypes .add (resolvableType );
546
- }
547
- break ;
548
- }
549
- }
518
+ private static final LinkedMultiValueMap <GraphQLType , ResolvableType > EMPTY_MAP = new LinkedMultiValueMap <>(0 );
550
519
551
- if (resolvableTypes .isEmpty ()) {
552
- resolvableTypes .add (ResolvableType .NONE );
553
- }
520
+ /** Interface or union type name to implementing or member GraphQL-Java types pairs. */
521
+ private final Map <String , MultiValueMap <GraphQLType , ResolvableType >> mappings ;
554
522
555
- for (ResolvableType resolvableType : resolvableTypes ) {
556
- String name = interfaceOrUnionType .getName ();
557
- this .mappings .computeIfAbsent (name , (n ) -> new LinkedMultiValueMap <>()).add (objectType , resolvableType );
558
- }
523
+ private InterfaceUnionLookup (Map <String , MultiValueMap <GraphQLType , ResolvableType >> mappings ) {
524
+ this .mappings = mappings ;
559
525
}
560
526
561
527
/**
@@ -565,7 +531,7 @@ private void addTypeMapping(
565
531
* pair with {@link ResolvableType#NONE}.
566
532
*/
567
533
MultiValueMap <GraphQLType , ResolvableType > resolveInterface (GraphQLInterfaceType interfaceType ) {
568
- return this .mappings .getOrDefault (interfaceType .getName (), EMPTY_MULTI_VALUE_MAP );
534
+ return this .mappings .getOrDefault (interfaceType .getName (), EMPTY_MAP );
569
535
}
570
536
571
537
/**
@@ -575,9 +541,61 @@ MultiValueMap<GraphQLType, ResolvableType> resolveInterface(GraphQLInterfaceType
575
541
* pair with {@link ResolvableType#NONE}.
576
542
*/
577
543
MultiValueMap <GraphQLType , ResolvableType > resolveUnion (GraphQLUnionType unionType ) {
578
- return this .mappings .getOrDefault (unionType .getName (), EMPTY_MULTI_VALUE_MAP );
544
+ return this .mappings .getOrDefault (unionType .getName (), EMPTY_MAP );
545
+ }
546
+
547
+ /**
548
+ * Resolve the class for every union member and interface implementation type,
549
+ * and create a lookup instance.
550
+ */
551
+ public static InterfaceUnionLookup create (
552
+ GraphQLSchema schema , List <ClassResolver > classResolvers ) {
553
+
554
+ Map <String , MultiValueMap <GraphQLType , ResolvableType >> mappings = new LinkedHashMap <>();
555
+
556
+ for (GraphQLNamedType type : schema .getAllTypesAsList ()) {
557
+ if (type instanceof GraphQLUnionType union ) {
558
+ for (GraphQLNamedOutputType member : union .getTypes ()) {
559
+ addTypeMapping (union , (GraphQLObjectType ) member , classResolvers , mappings );
560
+ }
561
+ }
562
+ else if (type instanceof GraphQLObjectType objectType ) {
563
+ for (GraphQLNamedOutputType interfaceType : objectType .getInterfaces ()) {
564
+ addTypeMapping (interfaceType , objectType , classResolvers , mappings );
565
+ }
566
+ }
567
+ }
568
+
569
+ return new InterfaceUnionLookup (mappings );
579
570
}
580
571
572
+ private static void addTypeMapping (
573
+ GraphQLNamedOutputType interfaceOrUnionType , GraphQLObjectType objectType ,
574
+ List <ClassResolver > classResolvers ,
575
+ Map <String , MultiValueMap <GraphQLType , ResolvableType >> mappings ) {
576
+
577
+ List <ResolvableType > resolvableTypes = new ArrayList <>();
578
+
579
+ for (ClassResolver resolver : classResolvers ) {
580
+ List <Class <?>> classes = resolver .resolveClass (objectType , interfaceOrUnionType );
581
+ if (!classes .isEmpty ()) {
582
+ for (Class <?> clazz : classes ) {
583
+ ResolvableType resolvableType = ResolvableType .forClass (clazz );
584
+ resolvableTypes .add (resolvableType );
585
+ }
586
+ break ;
587
+ }
588
+ }
589
+
590
+ if (resolvableTypes .isEmpty ()) {
591
+ resolvableTypes .add (ResolvableType .NONE );
592
+ }
593
+
594
+ for (ResolvableType resolvableType : resolvableTypes ) {
595
+ String name = interfaceOrUnionType .getName ();
596
+ mappings .computeIfAbsent (name , (n ) -> new LinkedMultiValueMap <>()).add (objectType , resolvableType );
597
+ }
598
+ }
581
599
}
582
600
583
601
0 commit comments