2424import java .lang .reflect .Field ;
2525import java .lang .reflect .Member ;
2626import 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 ;
2832import java .util .concurrent .atomic .AtomicInteger ;
2933import java .util .stream .Collectors ;
3034import java .util .stream .Stream ;
4751import com .introproventures .graphql .jpa .query .schema .GraphQLSchemaBuilder ;
4852import com .introproventures .graphql .jpa .query .schema .JavaScalars ;
4953import com .introproventures .graphql .jpa .query .schema .NamingStrategy ;
54+ import com .introproventures .graphql .jpa .query .schema .impl .IntrospectionUtils .CachedIntrospectionResult .CachedPropertyDescriptor ;
5055import com .introproventures .graphql .jpa .query .schema .impl .PredicateFilter .Criteria ;
5156
5257import graphql .Assert ;
@@ -92,7 +97,7 @@ public class GraphQLJpaSchemaBuilder implements GraphQLSchemaBuilder {
9297
9398 public static final String ORDER_BY_PARAM_NAME = "orderBy" ;
9499
95- private Map <Class <?>, GraphQLType > classCache = new HashMap <>();
100+ private Map <Class <?>, GraphQLOutputType > classCache = new HashMap <>();
96101 private Map <EntityType <?>, GraphQLObjectType > entityCache = new HashMap <>();
97102 private Map <EmbeddableType <?>, GraphQLObjectType > embeddableOutputCache = new HashMap <>();
98103 private Map <EmbeddableType <?>, GraphQLInputObjectType > embeddableInputCache = new HashMap <>();
@@ -205,7 +210,7 @@ private GraphQLArgument getWhereArgument(ManagedType<?> managedType) {
205210 if (managedType instanceof EmbeddableType ){
206211 typeName = managedType .getJavaType ().getSimpleName ()+"EmbeddableType" ;
207212 } else if (managedType instanceof EntityType ) {
208- typeName = ((EntityType )managedType ).getName ();
213+ typeName = ((EntityType <?> )managedType ).getName ();
209214 }
210215
211216 String type = namingStrategy .pluralize (typeName )+"CriteriaExpression" ;
@@ -251,14 +256,14 @@ private GraphQLArgument getWhereArgument(ManagedType<?> managedType) {
251256 }
252257
253258 private GraphQLInputObjectField getWhereInputField (Attribute <?,?> attribute ) {
254- GraphQLType type = getWhereAttributeType (attribute );
259+ GraphQLInputType type = getWhereAttributeType (attribute );
255260 String description = getSchemaDescription (attribute .getJavaMember ());
256261
257262 if (type instanceof GraphQLInputType ) {
258263 return GraphQLInputObjectField .newInputObjectField ()
259264 .name (attribute .getName ())
260265 .description (description )
261- .type (( GraphQLInputType ) type )
266+ .type (type )
262267 .build ();
263268 }
264269
@@ -409,7 +414,7 @@ private GraphQLArgument getArgument(Attribute<?,?> attribute) {
409414
410415 return GraphQLArgument .newArgument ()
411416 .name (attribute .getName ())
412- .type (( GraphQLInputType ) type )
417+ .type (type )
413418 .description (description )
414419 .build ();
415420 }
@@ -454,89 +459,51 @@ private GraphQLType getEmbeddableType(EmbeddableType<?> embeddableType, boolean
454459
455460
456461 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 );
504463 }
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 ();
517473 }
518474
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+ }
528482
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 ());
531498
532499 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 )
536503 .dataFetcher (dataFetcher )
537504 .build ();
538505 }
539-
506+
540507 @ SuppressWarnings ( { "rawtypes" , "unchecked" } )
541508 private GraphQLFieldDefinition getObjectField (Attribute attribute ) {
542509 GraphQLOutputType type = getAttributeOutputType (attribute );
@@ -583,7 +550,7 @@ else if (attribute instanceof PluralAttribute
583550 .build ();
584551 }
585552
586- @ SuppressWarnings ( { "rawtypes" , "unchecked" } )
553+ @ SuppressWarnings ( { "rawtypes" } )
587554 private GraphQLInputObjectField getInputObjectField (Attribute attribute ) {
588555 GraphQLInputType type = getAttributeInputType (attribute );
589556
@@ -598,7 +565,6 @@ private Stream<Attribute<?,?>> findBasicAttributes(Collection<Attribute<?,?>> at
598565 return attributes .stream ().filter (it -> it .getPersistentAttributeType () == Attribute .PersistentAttributeType .BASIC );
599566 }
600567
601- @ SuppressWarnings ( "rawtypes" )
602568 private GraphQLInputType getAttributeInputType (Attribute <?,?> attribute ) {
603569 try {
604570 return (GraphQLInputType ) getAttributeType (attribute , true );
@@ -607,7 +573,6 @@ private GraphQLInputType getAttributeInputType(Attribute<?,?> attribute) {
607573 }
608574 }
609575
610- @ SuppressWarnings ( "rawtypes" )
611576 private GraphQLOutputType getAttributeOutputType (Attribute <?,?> attribute ) {
612577 try {
613578 return (GraphQLOutputType ) getAttributeType (attribute , false );
@@ -786,7 +751,7 @@ private boolean isNotIgnored(AnnotatedElement annotatedElement) {
786751 }
787752
788753 @ SuppressWarnings ( "unchecked" )
789- private GraphQLType getGraphQLTypeFromJavaType (Class <?> clazz ) {
754+ private GraphQLOutputType getGraphQLTypeFromJavaType (Class <?> clazz ) {
790755 if (clazz .isEnum ()) {
791756
792757 if (classCache .containsKey (clazz ))
@@ -797,7 +762,7 @@ private GraphQLType getGraphQLTypeFromJavaType(Class<?> clazz) {
797762 for (Enum <?> enumValue : ((Class <Enum <?>>)clazz ).getEnumConstants ())
798763 enumBuilder .value (enumValue .name (), ordinal ++);
799764
800- GraphQLType enumType = enumBuilder .build ();
765+ GraphQLEnumType enumType = enumBuilder .build ();
801766 setNoOpCoercing (enumType );
802767
803768 classCache .putIfAbsent (clazz , enumType );
0 commit comments