diff --git a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/type/TypeCreator.java b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/type/TypeCreator.java index 46f36b86f..df97861cd 100644 --- a/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/type/TypeCreator.java +++ b/common/schema-builder/src/main/java/io/smallrye/graphql/schema/creator/type/TypeCreator.java @@ -1,11 +1,6 @@ package io.smallrye.graphql.schema.creator.type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -45,28 +40,34 @@ public TypeCreator(ReferenceCreator referenceCreator, FieldCreator fieldCreator, @Override protected void addFields(Type type, ClassInfo classInfo, Reference reference) { // Fields - List allMethods = new ArrayList<>(); + List> allMethods = new LinkedList<>(); Map allFields = new HashMap<>(); // Find all methods and properties up the tree for (ClassInfo c = classInfo; c != null; c = ScanningContext.getIndex().getClassByName(c.superName())) { + List listMethods = new ArrayList<>(); + if (InterfaceCreator.canAddInterfaceIntoScheme(c.toString())) { // Not java objects List classMethods = filterOutBridgeMethod(c.methods()); - allMethods.addAll(classMethods); - allMethods.addAll(getAllInterfaceMethods(c, classMethods + listMethods.addAll(getAllInterfaceMethods(c, classMethods .stream() .map(MethodInfo::toString) .collect(Collectors.toSet()))); + listMethods.addAll(classMethods); for (FieldInfo fieldInfo : c.fields()) { allFields.putIfAbsent(fieldInfo.name(), fieldInfo); } } + + allMethods.add(0, listMethods); } - for (MethodInfo methodInfo : allMethods) { - if (MethodHelper.isPropertyMethod(Direction.OUT, methodInfo)) { - String fieldName = MethodHelper.getPropertyName(Direction.OUT, methodInfo.name()); - FieldInfo fieldInfo = allFields.remove(fieldName); - fieldCreator.createFieldForPojo(Direction.OUT, fieldInfo, methodInfo, reference).ifPresent(type::addField); + for (List listMethods : allMethods) { + for (MethodInfo methodInfo : listMethods) { + if (MethodHelper.isPropertyMethod(Direction.OUT, methodInfo)) { + String fieldName = MethodHelper.getPropertyName(Direction.OUT, methodInfo.name()); + FieldInfo fieldInfo = allFields.remove(fieldName); + fieldCreator.createFieldForPojo(Direction.OUT, fieldInfo, methodInfo, reference).ifPresent(type::addField); + } } } diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java b/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java index 9ff1770ac..0b46251e5 100644 --- a/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/index/SchemaBuilderTest.java @@ -171,6 +171,28 @@ public void testSchemaWithBatchSourceFieldNameDuplicates() { } } + @Test + public void testSchemaWithInheritFieldBySubtype() { + Indexer indexer = new Indexer(); + indexDirectory(indexer, "io/smallrye/graphql/index/inherit/"); + + IndexView index = indexer.complete(); + Schema schema = SchemaBuilder.build(index); + // Get Types + Map types = schema.getTypes(); + Map interfaces = schema.getInterfaces(); + Type containerType = types.get("ContainerType"); + Field containerTypeField = containerType.getFields().get("inheritField"); + Type containerInterface = interfaces.get("ContainerInterface"); + Field containerInterfaceField = containerInterface.getFields().get("inheritField"); + + // Should be FieldType according to GraphQL Spec: https://spec.graphql.org/October2021/#sec-Objects.Type-Validation + assertEquals("io.smallrye.graphql.index.inherit.FieldType", + containerTypeField.getReference().getClassName()); + assertEquals("io.smallrye.graphql.index.inherit.FieldInterface", + containerInterfaceField.getReference().getClassName()); + } + @Test public void testSchemaWithDirectives() throws IOException { Indexer indexer = new Indexer(); diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/ContainerInterface.java b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/ContainerInterface.java new file mode 100644 index 000000000..0305f0b49 --- /dev/null +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/ContainerInterface.java @@ -0,0 +1,5 @@ +package io.smallrye.graphql.index.inherit; + +public interface ContainerInterface { + FieldInterface getInheritField(); +} diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/ContainerType.java b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/ContainerType.java new file mode 100644 index 000000000..a418fe7c9 --- /dev/null +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/ContainerType.java @@ -0,0 +1,8 @@ +package io.smallrye.graphql.index.inherit; + +public class ContainerType implements ContainerInterface { + + public FieldType getInheritField() { + return new FieldType(); + } +} diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/FieldInterface.java b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/FieldInterface.java new file mode 100644 index 000000000..573debaa4 --- /dev/null +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/FieldInterface.java @@ -0,0 +1,5 @@ +package io.smallrye.graphql.index.inherit; + +public interface FieldInterface { + String getVal(); +} diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/FieldType.java b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/FieldType.java new file mode 100644 index 000000000..57bdbae01 --- /dev/null +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/FieldType.java @@ -0,0 +1,7 @@ +package io.smallrye.graphql.index.inherit; + +public class FieldType implements FieldInterface { + public String getVal() { + return ""; + } +} diff --git a/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/InheritAPI.java b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/InheritAPI.java new file mode 100644 index 000000000..d3cb21a94 --- /dev/null +++ b/common/schema-builder/src/test/java/io/smallrye/graphql/index/inherit/InheritAPI.java @@ -0,0 +1,12 @@ +package io.smallrye.graphql.index.inherit; + +import org.eclipse.microprofile.graphql.GraphQLApi; +import org.eclipse.microprofile.graphql.Query; + +@GraphQLApi +public class InheritAPI { + @Query + public ContainerInterface getContainer() { + return null; + } +}