3333import static graphql .annotations .ReflectionKit .newInstance ;
3434import static graphql .annotations .util .NamingKit .toGraphqlName ;
3535import static graphql .schema .GraphQLArgument .newArgument ;
36+ import static graphql .schema .GraphQLEnumType .newEnum ;
3637import static graphql .schema .GraphQLFieldDefinition .newFieldDefinition ;
3738import static graphql .schema .GraphQLInputObjectField .newInputObjectField ;
3839import static graphql .schema .GraphQLInterfaceType .newInterface ;
@@ -50,7 +51,7 @@ public class GraphQLAnnotations implements GraphQLAnnotationsProcessor {
5051
5152 private static final List <Class > TYPES_FOR_CONNECTION = Arrays .asList (GraphQLObjectType .class , GraphQLInterfaceType .class , GraphQLUnionType .class , GraphQLTypeReference .class );
5253
53- private Map <String , graphql .schema .GraphQLType > typeRegistry = new HashMap <>();
54+ private Map <String , graphql .schema .GraphQLOutputType > typeRegistry = new HashMap <>();
5455 private Map <Class <?>, Set <Class <?>>> extensionsTypeRegistry = new HashMap <>();
5556 private final Stack <String > processing = new Stack <>();
5657 private Relay relay = new Relay ();
@@ -75,21 +76,8 @@ public void setRelay(Relay relay) {
7576 }
7677
7778 @ Override
78- public graphql .schema .GraphQLType getInterface (Class <?> iface ) throws GraphQLAnnotationsException {
79- String typeName = getTypeName (iface );
80- graphql .schema .GraphQLType type = typeRegistry .get (typeName );
81- if (type != null ) { // type already exists, do not build a new new one
82- return type ;
83- }
84- if (iface .getAnnotation (GraphQLUnion .class ) != null ) {
85- type = getUnionBuilder (iface ).build ();
86- } else if (!iface .isAnnotationPresent (GraphQLTypeResolver .class )) {
87- type = getObject (iface );
88- } else {
89- type = getIfaceBuilder (iface ).build ();
90- }
91- typeRegistry .put (typeName , type );
92- return type ;
79+ public graphql .schema .GraphQLOutputType getInterface (Class <?> iface ) throws GraphQLAnnotationsException {
80+ return getOutputType (iface );
9381 }
9482
9583 public static graphql .schema .GraphQLType iface (Class <?> iface ) throws GraphQLAnnotationsException {
@@ -252,26 +240,92 @@ private boolean parentalSearch(Field field) {
252240
253241 @ Override
254242 public GraphQLObjectType getObject (Class <?> object ) throws GraphQLAnnotationsException {
243+ GraphQLOutputType type = getOutputType (object );
244+ if (type instanceof GraphQLObjectType ) {
245+ return (GraphQLObjectType ) type ;
246+ } else {
247+ throw new IllegalArgumentException ("Object resolve to a " +type .getClass ().getSimpleName ());
248+ }
249+ }
250+
251+ @ Override
252+ public GraphQLOutputType getOutputType (Class <?> object ) throws GraphQLAnnotationsException {
255253 // because the TypeFunction can call back to this processor and
256254 // Java classes can be circular, we need to protect against
257255 // building the same type twice because graphql-java 3.x requires
258256 // all type instances to be unique singletons
259257 String typeName = getTypeName (object );
260- processing .push (typeName );
261258
262- GraphQLObjectType .Builder builder = getObjectBuilder (object );
259+ GraphQLOutputType type = typeRegistry .get (typeName );
260+ if (type != null ) { // type already exists, do not build a new new one
261+ return type ;
262+ }
263263
264+ processing .push (typeName );
265+ if (object .getAnnotation (GraphQLUnion .class ) != null ) {
266+ type = getUnionBuilder (object ).build ();
267+ } else if (object .isAnnotationPresent (GraphQLTypeResolver .class )) {
268+ type = getIfaceBuilder (object ).build ();
269+ } else if (Enum .class .isAssignableFrom (object )) {
270+ type = getEnumBuilder (object ).build ();
271+ } else {
272+ type = new GraphQLObjectTypeWrapper (object , getObjectBuilder (object ).build ());
273+ }
274+
275+ typeRegistry .put (typeName , type );
264276 processing .pop ();
265- return new GraphQLObjectTypeWrapper (object , builder .build ());
277+
278+ return type ;
279+ }
280+
281+ public static GraphQLOutputType outputType (Class <?> object ) {
282+ return getInstance ().getOutputType (object );
283+ }
284+
285+ public GraphQLEnumType .Builder getEnumBuilder (Class <?> aClass ) {
286+ String typeName = getTypeName (aClass );
287+ //noinspection unchecked
288+ Class <? extends Enum > enumClass = (Class <? extends Enum >) aClass ;
289+ GraphQLEnumType .Builder builder = newEnum ();
290+ builder .name (typeName );
291+
292+ GraphQLDescription description = aClass .getAnnotation (GraphQLDescription .class );
293+ if (description != null ) {
294+ builder .description (description .value ());
295+ }
296+
297+ List <Enum > constants = Arrays .asList (enumClass .getEnumConstants ());
298+
299+ Arrays .stream (enumClass .getEnumConstants ()).map (Enum ::name ).forEachOrdered (n -> {
300+ try {
301+ Field field = aClass .getField (n );
302+ GraphQLName fieldName = field .getAnnotation (GraphQLName .class );
303+ GraphQLDescription fieldDescription = field .getAnnotation (GraphQLDescription .class );
304+ Enum constant = constants .stream ().filter (c -> c .name ().contentEquals (n )).findFirst ().get ();
305+ String name_ = fieldName == null ? n : fieldName .value ();
306+ builder .value (name_ , constant , fieldDescription == null ? name_ : fieldDescription .value ());
307+ } catch (NoSuchFieldException ignore ) {
308+ }
309+ });
310+ return builder ;
311+ }
312+
313+ public static GraphQLEnumType .Builder enumBuilder (Class <?> object ) throws GraphQLAnnotationsException {
314+ return getInstance ().getEnumBuilder (object );
266315 }
267316
268- @ Override
269317 public GraphQLOutputType getObjectOrRef (Class <?> object ) throws GraphQLAnnotationsException {
318+ return getOutputTypeOrRef (object );
319+ }
320+
321+ @ Override
322+ public GraphQLOutputType getOutputTypeOrRef (Class <?> object ) throws GraphQLAnnotationsException {
270323 String typeName = getTypeName (object );
271324 if (processing .contains (typeName )) {
272325 return new GraphQLTypeReference (typeName );
273326 }
274- return getObject (object );
327+
328+ return getOutputType (object );
275329 }
276330
277331 public static GraphQLObjectType object (Class <?> object ) throws GraphQLAnnotationsException {
@@ -726,7 +780,7 @@ public static void register(TypeFunction typeFunction) {
726780 getInstance ().registerType (typeFunction );
727781 }
728782
729- public Map <String , graphql .schema .GraphQLType > getTypeRegistry () {
783+ public Map <String , graphql .schema .GraphQLOutputType > getTypeRegistry () {
730784 return typeRegistry ;
731785 }
732786
0 commit comments