diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapperFactory.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapperFactory.java index 7fe3a8825..26fe985a3 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapperFactory.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapperFactory.java @@ -23,14 +23,14 @@ public class DataModelMapperFactory { public DataModelMapperFactory(MapperFactory mapperFactory) { this.mapperFactory = mapperFactory; - this.fieldDefToParamMapper = new FieldDefinitionToParameterMapper(mapperFactory); + InputValueDefinitionToParameterMapper inputValueDefToParamMapper = new InputValueDefinitionToParameterMapper( + mapperFactory); + this.fieldDefToParamMapper = new FieldDefinitionToParameterMapper(mapperFactory, inputValueDefToParamMapper); this.enumDefToDataModelMapper = new EnumDefinitionToDataModelMapper(mapperFactory); this.unionDefToDataModelMapper = new UnionDefinitionToDataModelMapper(mapperFactory); this.typeDefToDataModelMapper = new TypeDefinitionToDataModelMapper(mapperFactory, fieldDefToParamMapper); this.interfaceDefToDataModelMapper = new InterfaceDefinitionToDataModelMapper( mapperFactory, fieldDefToParamMapper); - InputValueDefinitionToParameterMapper inputValueDefToParamMapper = new InputValueDefinitionToParameterMapper( - mapperFactory); this.inputDefToDataModelMapper = new InputDefinitionToDataModelMapper( mapperFactory, inputValueDefToParamMapper); this.fieldDefsToResolverDataModelMapper = new FieldDefinitionsToResolverDataModelMapper( diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/FieldDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/FieldDefinitionToParameterMapper.java index e9848ffb9..2e3603c1d 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/FieldDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/FieldDefinitionToParameterMapper.java @@ -23,11 +23,14 @@ public class FieldDefinitionToParameterMapper { private final GraphQLTypeMapper graphQLTypeMapper; private final DataModelMapper dataModelMapper; private final AnnotationsMapper annotationsMapper; + private final InputValueDefinitionToParameterMapper inputValueDefinitionToParameterMapper; - public FieldDefinitionToParameterMapper(MapperFactory mapperFactory) { + public FieldDefinitionToParameterMapper(MapperFactory mapperFactory, + InputValueDefinitionToParameterMapper inputValueDefToParamMapper) { this.graphQLTypeMapper = mapperFactory.getGraphQLTypeMapper(); this.dataModelMapper = mapperFactory.getDataModelMapper(); this.annotationsMapper = mapperFactory.getAnnotationsMapper(); + this.inputValueDefinitionToParameterMapper = inputValueDefToParamMapper; } /** @@ -137,6 +140,8 @@ private ParameterDefinition mapField(MappingContext mappingContext, ExtendedFiel parameter.setDeprecated(DeprecatedDefinitionBuilder.build(mappingContext, fieldDef)); parameter.setMandatory(namedDefinition.isMandatory()); parameter.setSerializeUsingObjectMapper(namedDefinition.isSerializeUsingObjectMapper()); + parameter.setInputParameters(inputValueDefinitionToParameterMapper.map( + mappingContext, fieldDef.getInputValueDefinitions(), fieldDef.getName())); return parameter; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java index 98d4a5290..435111613 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/ParameterDefinition.java @@ -31,6 +31,10 @@ public class ParameterDefinition { private List javaDoc = new ArrayList<>(); private DeprecatedDefinition deprecated; private boolean serializeUsingObjectMapper; + /** + * If the type is parametrized then input parameters will be defined here + */ + private List inputParameters; /** * Definition of the same type, but defined in the parent */ @@ -124,4 +128,12 @@ public ParameterDefinition getDefinitionInParentType() { public void setDefinitionInParentType(ParameterDefinition definitionInParentType) { this.definitionInParentType = definitionInParentType; } + + public List getInputParameters() { + return inputParameters; + } + + public void setInputParameters(List inputParameters) { + this.inputParameters = inputParameters; + } } diff --git a/src/main/resources/templates/java-lang/interface.ftl b/src/main/resources/templates/java-lang/interface.ftl index 4d55a9a2e..f3957e0b0 100644 --- a/src/main/resources/templates/java-lang/interface.ftl +++ b/src/main/resources/templates/java-lang/interface.ftl @@ -41,7 +41,7 @@ public interface ${className} <#if implements?has_content>extends <#list impleme <#list field.annotations as annotation> @${annotation} - ${field.type} get${field.name?cap_first}(); + ${field.type} get${field.name?cap_first}(<#list field.inputParameters as param><#list param.annotations as paramAnnotation>@${paramAnnotation}<#if param.annotations?has_content> ${param.type} ${param.name}<#if param_has_next>, ); diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTypesAsInterfacesTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTypesAsInterfacesTest.java index 91d063ec6..5eeff536d 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTypesAsInterfacesTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTypesAsInterfacesTest.java @@ -8,13 +8,13 @@ import org.junit.jupiter.api.Test; import java.io.File; -import java.util.Collections; import java.util.HashSet; import java.util.Objects; import static com.kobylynskyi.graphql.codegen.TestUtils.assertSameTrimmedContent; import static com.kobylynskyi.graphql.codegen.TestUtils.getFileByName; import static java.util.Arrays.asList; +import static java.util.Collections.singleton; import static java.util.Collections.singletonList; class GraphQLCodegenTypesAsInterfacesTest { @@ -26,7 +26,9 @@ class GraphQLCodegenTypesAsInterfacesTest { @BeforeEach void init() { mappingConfig.setPackageName("com.github.graphql"); - mappingConfig.setFieldsWithResolvers(Collections.singleton("@customResolver")); + mappingConfig.setFieldsWithResolvers(singleton("@customResolver")); + mappingConfig.setFieldsWithoutResolvers(singleton("@noResolver")); + mappingConfig.setTypesAsInterfaces(new HashSet<>(singleton("@asInterface"))); } @AfterEach @@ -36,7 +38,7 @@ void cleanup() { @Test void generate_typesAsInterfaces() throws Exception { - mappingConfig.setTypesAsInterfaces(new HashSet<>(asList("@asInterface", "Order"))); + mappingConfig.getTypesAsInterfaces().add("Order"); new JavaGraphQLCodegen(singletonList("src/test/resources/schemas/types-as-interfaces.graphqls"), outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); @@ -68,16 +70,31 @@ void generate_typesAsInterfacesExtendsInterface() throws Exception { assertSameTrimmedContent(new File("src/test/resources/expected-classes/" + "types-as-interfaces-extends-interface/Node.java.txt"), getFileByName(files, "Node.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/" + - "types-as-interfaces-extends-interface/Profile.java.txt"), + "types-as-interfaces-extends-interface/Profile.java.txt"), getFileByName(files, "Profile.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/" + - "types-as-interfaces-extends-interface/QueryResolver.java.txt"), + "types-as-interfaces-extends-interface/QueryResolver.java.txt"), getFileByName(files, "QueryResolver.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/" + "types-as-interfaces-extends-interface/User.java.txt"), getFileByName(files, "User.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/" + - "types-as-interfaces-extends-interface/UserCurrentQueryResolver.java.txt"), + "types-as-interfaces-extends-interface/UserCurrentQueryResolver.java.txt"), getFileByName(files, "UserCurrentQueryResolver.java")); } + @Test + void generate_typeAsInterfaceParametrized() throws Exception { + mappingConfig.setGenerateParameterizedFieldsResolvers(true); + + new JavaGraphQLCodegen(singletonList("src/test/resources/schemas/" + + "types-as-interfaces-parametrized.graphqls"), + outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo()).generate(); + + File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles()); + + assertSameTrimmedContent(new File( + "src/test/resources/expected-classes/types-as-interfaces-parametrized/Foo.java.txt"), + getFileByName(files, "Foo.java")); + } + } diff --git a/src/test/resources/expected-classes/ProfileOwner.java.txt b/src/test/resources/expected-classes/ProfileOwner.java.txt index aecfc03a2..0cb9bf1d6 100644 --- a/src/test/resources/expected-classes/ProfileOwner.java.txt +++ b/src/test/resources/expected-classes/ProfileOwner.java.txt @@ -7,7 +7,7 @@ package com.github.graphql; ) public interface ProfileOwner { - boolean getAnyPinnableItems(); + boolean getAnyPinnableItems(PinnableItemType type); String getEmail(); @@ -25,10 +25,10 @@ public interface ProfileOwner { String getName(); @javax.validation.constraints.NotNull - PinnableItemConnection getPinnableItems(); + PinnableItemConnection getPinnableItems(String after, String before, Integer first, Integer last, @javax.validation.constraints.NotNull java.util.List types); @javax.validation.constraints.NotNull - PinnableItemConnection getPinnedItems(); + PinnableItemConnection getPinnedItems(String after, String before, Integer first, Integer last, @javax.validation.constraints.NotNull java.util.List types); int getPinnedItemsRemaining(); diff --git a/src/test/resources/expected-classes/types-as-interfaces-parametrized/Foo.java.txt b/src/test/resources/expected-classes/types-as-interfaces-parametrized/Foo.java.txt new file mode 100644 index 000000000..554307732 --- /dev/null +++ b/src/test/resources/expected-classes/types-as-interfaces-parametrized/Foo.java.txt @@ -0,0 +1,16 @@ +package com.github.graphql; + + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public interface Foo { + + @javax.validation.constraints.NotNull + String getSimpleField(); + + @javax.validation.constraints.NotNull + String getParameterizedField(int count); + +} \ No newline at end of file diff --git a/src/test/resources/schemas/types-as-interfaces-parametrized.graphqls b/src/test/resources/schemas/types-as-interfaces-parametrized.graphqls new file mode 100644 index 000000000..67d7ba604 --- /dev/null +++ b/src/test/resources/schemas/types-as-interfaces-parametrized.graphqls @@ -0,0 +1,14 @@ +""" +used with typesAsInterfaces config +""" +directive @asInterface on OBJECT + +""" +used with fieldsWithResolvers config +""" +directive @noResolver on FIELD_DEFINITION + +type Foo @asInterface { + simpleField: String! + parameterizedField(count: Int!): String! @noResolver +} \ No newline at end of file