24
24
import java .lang .reflect .Field ;
25
25
import java .lang .reflect .Member ;
26
26
import java .lang .reflect .Method ;
27
- import java .util .*;
27
+ import java .util .ArrayList ;
28
+ import java .util .Collection ;
29
+ import java .util .HashMap ;
30
+ import java .util .List ;
31
+ import java .util .Map ;
28
32
import java .util .concurrent .atomic .AtomicInteger ;
29
33
import java .util .stream .Collectors ;
30
34
import java .util .stream .Stream ;
47
51
import com .introproventures .graphql .jpa .query .schema .GraphQLSchemaBuilder ;
48
52
import com .introproventures .graphql .jpa .query .schema .JavaScalars ;
49
53
import com .introproventures .graphql .jpa .query .schema .NamingStrategy ;
54
+ import com .introproventures .graphql .jpa .query .schema .impl .IntrospectionUtils .CachedIntrospectionResult .CachedPropertyDescriptor ;
50
55
import com .introproventures .graphql .jpa .query .schema .impl .PredicateFilter .Criteria ;
51
56
52
57
import graphql .Assert ;
@@ -92,7 +97,7 @@ public class GraphQLJpaSchemaBuilder implements GraphQLSchemaBuilder {
92
97
93
98
public static final String ORDER_BY_PARAM_NAME = "orderBy" ;
94
99
95
- private Map <Class <?>, GraphQLType > classCache = new HashMap <>();
100
+ private Map <Class <?>, GraphQLOutputType > classCache = new HashMap <>();
96
101
private Map <EntityType <?>, GraphQLObjectType > entityCache = new HashMap <>();
97
102
private Map <EmbeddableType <?>, GraphQLObjectType > embeddableOutputCache = new HashMap <>();
98
103
private Map <EmbeddableType <?>, GraphQLInputObjectType > embeddableInputCache = new HashMap <>();
@@ -205,7 +210,7 @@ private GraphQLArgument getWhereArgument(ManagedType<?> managedType) {
205
210
if (managedType instanceof EmbeddableType ){
206
211
typeName = managedType .getJavaType ().getSimpleName ()+"EmbeddableType" ;
207
212
} else if (managedType instanceof EntityType ) {
208
- typeName = ((EntityType )managedType ).getName ();
213
+ typeName = ((EntityType <?> )managedType ).getName ();
209
214
}
210
215
211
216
String type = namingStrategy .pluralize (typeName )+"CriteriaExpression" ;
@@ -251,14 +256,14 @@ private GraphQLArgument getWhereArgument(ManagedType<?> managedType) {
251
256
}
252
257
253
258
private GraphQLInputObjectField getWhereInputField (Attribute <?,?> attribute ) {
254
- GraphQLType type = getWhereAttributeType (attribute );
259
+ GraphQLInputType type = getWhereAttributeType (attribute );
255
260
String description = getSchemaDescription (attribute .getJavaMember ());
256
261
257
262
if (type instanceof GraphQLInputType ) {
258
263
return GraphQLInputObjectField .newInputObjectField ()
259
264
.name (attribute .getName ())
260
265
.description (description )
261
- .type (( GraphQLInputType ) type )
266
+ .type (type )
262
267
.build ();
263
268
}
264
269
@@ -409,7 +414,7 @@ private GraphQLArgument getArgument(Attribute<?,?> attribute) {
409
414
410
415
return GraphQLArgument .newArgument ()
411
416
.name (attribute .getName ())
412
- .type (( GraphQLInputType ) type )
417
+ .type (type )
413
418
.description (description )
414
419
.build ();
415
420
}
@@ -454,89 +459,51 @@ private GraphQLType getEmbeddableType(EmbeddableType<?> embeddableType, boolean
454
459
455
460
456
461
private GraphQLObjectType getObjectType (EntityType <?> entityType ) {
457
- if (entityCache .containsKey (entityType ))
458
- return entityCache .get (entityType );
459
-
460
-
461
- GraphQLObjectType objectType = GraphQLObjectType .newObject ()
462
- .name (entityType .getName ())
463
- .description (getSchemaDescription ( entityType .getJavaType ()))
464
- .fields (entityType .getAttributes ().stream ()
465
- .filter (this ::isNotIgnored )
466
- .map (this ::getObjectField )
467
- .collect (Collectors .toList ())
468
- )
469
- .fields (getObjectCalcFields (entityType .getJavaType ()))
470
- .fields (getObjectCalcMethods (entityType .getJavaType ()))
471
- .build ();
472
-
473
- entityCache .putIfAbsent (entityType , objectType );
474
-
475
- return objectType ;
476
- }
477
-
478
- private List <GraphQLFieldDefinition > getObjectCalcFields (Class cls ) {
479
- return
480
- Arrays .stream (cls .getDeclaredFields ())
481
- .filter (
482
- f ->
483
- f instanceof Member &&
484
- f .isAnnotationPresent (Transient .class ) &&
485
- isNotIgnored ((Member ) f ) &&
486
- isNotIgnored (f .getType ())
487
- )
488
- .map (f -> getObjectCalcField (f ))
489
- .collect (Collectors .toList ());
490
- }
491
-
492
- private List <GraphQLFieldDefinition > getObjectCalcMethods (Class cls ) {
493
- return
494
- Arrays .stream (cls .getDeclaredMethods ())
495
- .filter (
496
- m ->
497
- m instanceof Member &&
498
- m .isAnnotationPresent (Transient .class ) &&
499
- isNotIgnored ((Member ) m ) &&
500
- isNotIgnored (m .getReturnType ())
501
- )
502
- .map (m -> getObjectCalcMethtod (m ))
503
- .collect (Collectors .toList ());
462
+ return entityCache .computeIfAbsent (entityType , this ::computeObjectType );
504
463
}
505
-
506
- @ SuppressWarnings ( { "rawtypes" , "unchecked" } )
507
- private GraphQLFieldDefinition getObjectCalcField (Field field ) {
508
- GraphQLType type = getGraphQLTypeFromJavaType (field .getType ());
509
- DataFetcher dataFetcher = PropertyDataFetcher .fetching (field .getName ());
510
-
511
- return GraphQLFieldDefinition .newFieldDefinition ()
512
- .name (field .getName ())
513
- .description (getSchemaDescription ((AnnotatedElement ) field ))
514
- .type ((GraphQLOutputType ) type )
515
- .dataFetcher (dataFetcher )
516
- .build ();
464
+
465
+
466
+ private GraphQLObjectType computeObjectType (EntityType <?> entityType ) {
467
+ return GraphQLObjectType .newObject ()
468
+ .name (entityType .getName ())
469
+ .description (getSchemaDescription (entityType .getJavaType ()))
470
+ .fields (getEntityAttributesFields (entityType ))
471
+ .fields (getTransientFields (entityType .getJavaType ()))
472
+ .build ();
517
473
}
518
474
519
- @ SuppressWarnings ( { "rawtypes" , "unchecked" } )
520
- private GraphQLFieldDefinition getObjectCalcMethtod (Method method ) {
521
- String nm = method .getName ();
522
- if (nm .startsWith ("is" )) {
523
- nm = Introspector .decapitalize (nm .substring (2 ));
524
- }
525
- if (nm .startsWith ("get" )) {
526
- nm = Introspector .decapitalize (nm .substring (3 ));
527
- }
475
+ private List <GraphQLFieldDefinition > getEntityAttributesFields (EntityType <?> entityType ) {
476
+ return entityType .getAttributes ()
477
+ .stream ()
478
+ .filter (this ::isNotIgnored )
479
+ .map (this ::getObjectField )
480
+ .collect (Collectors .toList ());
481
+ }
528
482
529
- GraphQLType type = getGraphQLTypeFromJavaType (method .getReturnType ());
530
- DataFetcher dataFetcher = PropertyDataFetcher .fetching (nm );
483
+
484
+ private List <GraphQLFieldDefinition > getTransientFields (Class <?> clazz ) {
485
+ return IntrospectionUtils .introspect (clazz )
486
+ .getPropertyDescriptors ().stream ()
487
+ .filter (it -> it .isAnnotationPresent (Transient .class ))
488
+ .map (CachedPropertyDescriptor ::getDelegate )
489
+ .filter (it -> isNotIgnored (it .getPropertyType ()))
490
+ .map (this ::getJavaFieldDefinition )
491
+ .collect (Collectors .toList ());
492
+ }
493
+
494
+ @ SuppressWarnings ( { "rawtypes" } )
495
+ private GraphQLFieldDefinition getJavaFieldDefinition (PropertyDescriptor propertyDescriptor ) {
496
+ GraphQLOutputType type = getGraphQLTypeFromJavaType (propertyDescriptor .getPropertyType ());
497
+ DataFetcher dataFetcher = PropertyDataFetcher .fetching (propertyDescriptor .getName ());
531
498
532
499
return GraphQLFieldDefinition .newFieldDefinition ()
533
- .name (nm )
534
- .description (getSchemaDescription (( AnnotatedElement ) method ))
535
- .type (( GraphQLOutputType ) type )
500
+ .name (propertyDescriptor . getName () )
501
+ .description (getSchemaDescription (propertyDescriptor . getPropertyType () ))
502
+ .type (type )
536
503
.dataFetcher (dataFetcher )
537
504
.build ();
538
505
}
539
-
506
+
540
507
@ SuppressWarnings ( { "rawtypes" , "unchecked" } )
541
508
private GraphQLFieldDefinition getObjectField (Attribute attribute ) {
542
509
GraphQLOutputType type = getAttributeOutputType (attribute );
@@ -583,7 +550,7 @@ else if (attribute instanceof PluralAttribute
583
550
.build ();
584
551
}
585
552
586
- @ SuppressWarnings ( { "rawtypes" , "unchecked" } )
553
+ @ SuppressWarnings ( { "rawtypes" } )
587
554
private GraphQLInputObjectField getInputObjectField (Attribute attribute ) {
588
555
GraphQLInputType type = getAttributeInputType (attribute );
589
556
@@ -598,7 +565,6 @@ private Stream<Attribute<?,?>> findBasicAttributes(Collection<Attribute<?,?>> at
598
565
return attributes .stream ().filter (it -> it .getPersistentAttributeType () == Attribute .PersistentAttributeType .BASIC );
599
566
}
600
567
601
- @ SuppressWarnings ( "rawtypes" )
602
568
private GraphQLInputType getAttributeInputType (Attribute <?,?> attribute ) {
603
569
try {
604
570
return (GraphQLInputType ) getAttributeType (attribute , true );
@@ -607,7 +573,6 @@ private GraphQLInputType getAttributeInputType(Attribute<?,?> attribute) {
607
573
}
608
574
}
609
575
610
- @ SuppressWarnings ( "rawtypes" )
611
576
private GraphQLOutputType getAttributeOutputType (Attribute <?,?> attribute ) {
612
577
try {
613
578
return (GraphQLOutputType ) getAttributeType (attribute , false );
@@ -786,7 +751,7 @@ private boolean isNotIgnored(AnnotatedElement annotatedElement) {
786
751
}
787
752
788
753
@ SuppressWarnings ( "unchecked" )
789
- private GraphQLType getGraphQLTypeFromJavaType (Class <?> clazz ) {
754
+ private GraphQLOutputType getGraphQLTypeFromJavaType (Class <?> clazz ) {
790
755
if (clazz .isEnum ()) {
791
756
792
757
if (classCache .containsKey (clazz ))
@@ -797,7 +762,7 @@ private GraphQLType getGraphQLTypeFromJavaType(Class<?> clazz) {
797
762
for (Enum <?> enumValue : ((Class <Enum <?>>)clazz ).getEnumConstants ())
798
763
enumBuilder .value (enumValue .name (), ordinal ++);
799
764
800
- GraphQLType enumType = enumBuilder .build ();
765
+ GraphQLEnumType enumType = enumBuilder .build ();
801
766
setNoOpCoercing (enumType );
802
767
803
768
classCache .putIfAbsent (clazz , enumType );
0 commit comments