1616
1717package com .introproventures .graphql .jpa .query .schema .impl ;
1818
19- import java .beans .BeanInfo ;
20- import java .beans .IntrospectionException ;
21- import java .beans .Introspector ;
22- import java .beans .PropertyDescriptor ;
2319import java .lang .reflect .AnnotatedElement ;
2420import java .lang .reflect .Field ;
2521import java .lang .reflect .Member ;
26- import java .lang .reflect .Method ;
2722import java .util .ArrayList ;
2823import java .util .Collection ;
2924import java .util .HashMap ;
4641import org .slf4j .Logger ;
4742import org .slf4j .LoggerFactory ;
4843
49- import com .introproventures .graphql .jpa .query .annotation .GraphQLDescription ;
5044import com .introproventures .graphql .jpa .query .annotation .GraphQLIgnore ;
5145import com .introproventures .graphql .jpa .query .annotation .GraphQLIgnoreFilter ;
5246import com .introproventures .graphql .jpa .query .annotation .GraphQLIgnoreOrder ;
5347import com .introproventures .graphql .jpa .query .schema .GraphQLSchemaBuilder ;
5448import com .introproventures .graphql .jpa .query .schema .JavaScalars ;
5549import com .introproventures .graphql .jpa .query .schema .NamingStrategy ;
56- import com .introproventures .graphql .jpa .query .schema .impl .IntrospectionUtils .CachedIntrospectionResult . CachedPropertyDescriptor ;
50+ import com .introproventures .graphql .jpa .query .schema .impl .IntrospectionUtils .EntityIntrospectionResult . AttributePropertyDescriptor ;
5751import com .introproventures .graphql .jpa .query .schema .impl .PredicateFilter .Criteria ;
5852
5953import graphql .Assert ;
@@ -164,7 +158,7 @@ private GraphQLObjectType getQueryType() {
164158 private GraphQLFieldDefinition getQueryFieldByIdDefinition (EntityType <?> entityType ) {
165159 return GraphQLFieldDefinition .newFieldDefinition ()
166160 .name (entityType .getName ())
167- .description (getSchemaDescription ( entityType . getJavaType () ))
161+ .description (getSchemaDescription (entityType ))
168162 .type (getObjectType (entityType ))
169163 .dataFetcher (new GraphQLJpaSimpleDataFetcher (entityManager , entityType , toManyDefaultOptional ))
170164 .argument (entityType .getAttributes ().stream ()
@@ -426,7 +420,7 @@ private GraphQLInputObjectField getWhereInputRelationField(Attribute<?,?> attrib
426420 ManagedType <?> foreignType = getForeignType (attribute );
427421
428422 String type = resolveWhereInputTypeName (foreignType );
429- String description = getSchemaDescription (attribute . getJavaMember () );
423+ String description = getSchemaDescription (attribute );
430424
431425 return GraphQLInputObjectField .newInputObjectField ()
432426 .name (attribute .getName ())
@@ -437,7 +431,7 @@ private GraphQLInputObjectField getWhereInputRelationField(Attribute<?,?> attrib
437431
438432 private GraphQLInputObjectField getWhereInputField (Attribute <?,?> attribute ) {
439433 GraphQLInputType type = getWhereAttributeType (attribute );
440- String description = getSchemaDescription (attribute . getJavaMember () );
434+ String description = getSchemaDescription (attribute );
441435
442436 if (type instanceof GraphQLInputType ) {
443437 return GraphQLInputObjectField .newInputObjectField ()
@@ -599,7 +593,7 @@ else if (attribute.getJavaMember().getClass().isAssignableFrom(Field.class)
599593
600594 private GraphQLArgument getArgument (Attribute <?,?> attribute ) {
601595 GraphQLInputType type = getAttributeInputType (attribute );
602- String description = getSchemaDescription (attribute . getJavaMember () );
596+ String description = getSchemaDescription (attribute );
603597
604598 return GraphQLArgument .newArgument ()
605599 .name (attribute .getName ())
@@ -619,7 +613,7 @@ private GraphQLType getEmbeddableType(EmbeddableType<?> embeddableType, boolean
619613 if (input ) {
620614 graphQLType = GraphQLInputObjectType .newInputObject ()
621615 .name (embeddableTypeName )
622- .description (getSchemaDescription (embeddableType . getJavaType () ))
616+ .description (getSchemaDescription (embeddableType ))
623617 .fields (embeddableType .getAttributes ().stream ()
624618 .filter (this ::isNotIgnored )
625619 .map (this ::getInputObjectField )
@@ -629,7 +623,7 @@ private GraphQLType getEmbeddableType(EmbeddableType<?> embeddableType, boolean
629623 } else {
630624 graphQLType = GraphQLObjectType .newObject ()
631625 .name (embeddableTypeName )
632- .description (getSchemaDescription (embeddableType . getJavaType () ))
626+ .description (getSchemaDescription (embeddableType ))
633627 .fields (embeddableType .getAttributes ().stream ()
634628 .filter (this ::isNotIgnored )
635629 .map (this ::getObjectField )
@@ -655,7 +649,7 @@ private GraphQLObjectType getObjectType(EntityType<?> entityType) {
655649 private GraphQLObjectType computeObjectType (EntityType <?> entityType ) {
656650 return GraphQLObjectType .newObject ()
657651 .name (entityType .getName ())
658- .description (getSchemaDescription (entityType . getJavaType () ))
652+ .description (getSchemaDescription (entityType ))
659653 .fields (getEntityAttributesFields (entityType ))
660654 .fields (getTransientFields (entityType .getJavaType ()))
661655 .build ();
@@ -673,27 +667,29 @@ private List<GraphQLFieldDefinition> getEntityAttributesFields(EntityType<?> ent
673667 private List <GraphQLFieldDefinition > getTransientFields (Class <?> clazz ) {
674668 return IntrospectionUtils .introspect (clazz )
675669 .getPropertyDescriptors ().stream ()
676- .filter (it -> IntrospectionUtils .isTransient (clazz , it .getName ()))
677- .filter (it -> !it .isAnnotationPresent (GraphQLIgnore .class ))
678- .map (CachedPropertyDescriptor ::getDelegate )
670+ .filter (AttributePropertyDescriptor ::isTransient )
671+ .filter (AttributePropertyDescriptor ::isNotIgnored )
679672 .map (this ::getJavaFieldDefinition )
680673 .collect (Collectors .toList ());
681674 }
682675
683676 @ SuppressWarnings ( { "rawtypes" } )
684- private GraphQLFieldDefinition getJavaFieldDefinition (PropertyDescriptor propertyDescriptor ) {
677+ private GraphQLFieldDefinition getJavaFieldDefinition (AttributePropertyDescriptor propertyDescriptor ) {
685678 GraphQLOutputType type = getGraphQLTypeFromJavaType (propertyDescriptor .getPropertyType ());
686679 DataFetcher dataFetcher = PropertyDataFetcher .fetching (propertyDescriptor .getName ());
680+
681+ String description = propertyDescriptor .getSchemaDescription ()
682+ .orElse (null );
687683
688684 return GraphQLFieldDefinition .newFieldDefinition ()
689- .name (propertyDescriptor .getName ())
690- .description (getSchemaDescription ( propertyDescriptor . getPropertyType ()) )
691- .type (type )
692- .dataFetcher (dataFetcher )
693- .build ();
685+ .name (propertyDescriptor .getName ())
686+ .description (description )
687+ .type (type )
688+ .dataFetcher (dataFetcher )
689+ .build ();
694690 }
695691
696- private GraphQLFieldDefinition getObjectField (Attribute attribute ) {
692+ private GraphQLFieldDefinition getObjectField (Attribute <?,?> attribute ) {
697693 return getObjectField (attribute , null );
698694 }
699695
@@ -751,7 +747,7 @@ else if (attribute instanceof PluralAttribute
751747
752748 return GraphQLFieldDefinition .newFieldDefinition ()
753749 .name (attribute .getName ())
754- .description (getSchemaDescription (attribute . getJavaMember () ))
750+ .description (getSchemaDescription (attribute ))
755751 .type (type )
756752 .dataFetcher (dataFetcher )
757753 .argument (arguments )
@@ -780,7 +776,7 @@ private GraphQLInputObjectField getInputObjectField(Attribute attribute) {
780776
781777 return GraphQLInputObjectField .newInputObjectField ()
782778 .name (attribute .getName ())
783- .description (getSchemaDescription (attribute . getJavaMember () ))
779+ .description (getSchemaDescription (attribute ))
784780 .type (type )
785781 .build ();
786782 }
@@ -878,86 +874,27 @@ protected final boolean isValidAssociation(Attribute<?,?> attribute) {
878874 return isOneToMany (attribute ) || isToOne (attribute );
879875 }
880876
881-
882-
883- private String getSchemaDescription (Member member ) {
884- if (member instanceof AnnotatedElement ) {
885- String desc = getSchemaDescription ((AnnotatedElement ) member );
886- if (desc != null ) {
887- return (desc );
888- }
889- }
890-
891- //The given Member has no @GraphQLDescription set.
892- //If the Member is a Method it might be a getter/setter, see if the property it represents
893- //is annotated with @GraphQLDescription
894- //Alternatively if the Member is a Field its getter might be annotated, see if its getter
895- //is annotated with @GraphQLDescription
896- if (member instanceof Method ) {
897- Field fieldMember = getFieldByAccessor ((Method )member );
898- if (fieldMember != null ) {
899- return (getSchemaDescription ((AnnotatedElement ) fieldMember ));
900- }
901- } else if (member instanceof Field ) {
902- Method fieldGetter = getGetterOfField ((Field )member );
903- if (fieldGetter != null ) {
904- return (getSchemaDescription ((AnnotatedElement ) fieldGetter ));
905- }
906- }
907877
908- return null ;
878+ private String getSchemaDescription (Attribute <?,?> attribute ) {
879+ return IntrospectionUtils .introspect (attribute .getDeclaringType ()
880+ .getJavaType ())
881+ .getPropertyDescriptor (attribute )
882+ .flatMap (AttributePropertyDescriptor ::getSchemaDescription )
883+ .orElse (null );
909884 }
910-
911- private Method getGetterOfField (Field field ) {
912- try {
913- Class <?> clazz = field .getDeclaringClass ();
914- BeanInfo info = Introspector .getBeanInfo (clazz );
915- PropertyDescriptor [] props = info .getPropertyDescriptors ();
916- for (PropertyDescriptor pd : props ) {
917- if (pd .getName ().equals (field .getName ())) {
918- return (pd .getReadMethod ());
919- }
920- }
921- } catch (IntrospectionException e ) {
922- e .printStackTrace ();
923- }
924-
925- return (null );
926- }
927-
928- //from https://stackoverflow.com/questions/13192734/getting-a-property-field-name-using-getter-method-of-a-pojo-java-bean/13514566
929- private static Field getFieldByAccessor (Method method ) {
930- try {
931- Class <?> clazz = method .getDeclaringClass ();
932- BeanInfo info = Introspector .getBeanInfo (clazz );
933- PropertyDescriptor [] props = info .getPropertyDescriptors ();
934- for (PropertyDescriptor pd : props ) {
935- if (method .equals (pd .getWriteMethod ()) || method .equals (pd .getReadMethod ())) {
936- String fieldName = pd .getName ();
937- try {
938- return (clazz .getDeclaredField (fieldName ));
939- } catch (Throwable t ) {
940- log .error ("class '" + clazz .getName () + "' contains method '" + method .getName () + "' which is an accessor for a Field named '" + fieldName + "', error getting the field:" , t );
941- return (null );
942- }
943- }
944- }
945- } catch (Throwable t ) {
946- log .error ("error finding Field for accessor with name '" + method .getName () + "'" , t );
947- }
948-
949- return null ;
885+
886+ private String getSchemaDescription (EntityType <?> entityType ) {
887+ return IntrospectionUtils .introspect (entityType .getJavaType ())
888+ .getSchemaDescription ()
889+ .orElse (null );
950890 }
951891
952- private String getSchemaDescription (AnnotatedElement annotatedElement ) {
953- if (annotatedElement != null ) {
954- GraphQLDescription schemaDocumentation = annotatedElement .getAnnotation (GraphQLDescription .class );
955- return schemaDocumentation != null ? schemaDocumentation .value () : null ;
956- }
957-
958- return null ;
892+ private String getSchemaDescription (EmbeddableType <?> embeddableType ) {
893+ return IntrospectionUtils .introspect (embeddableType .getJavaType ())
894+ .getSchemaDescription ()
895+ .orElse (null );
959896 }
960-
897+
961898 private boolean isNotIgnored (EmbeddableType <?> attribute ) {
962899 return isNotIgnored (attribute .getJavaType ());
963900 }
0 commit comments