diff --git a/plugins/gradle/README.md b/plugins/gradle/README.md index 158494167..af7b8cfae 100644 --- a/plugins/gradle/README.md +++ b/plugins/gradle/README.md @@ -82,6 +82,7 @@ apply plugin: "io.github.kobylynskyi.graphql.codegen" | `generateRequests` | Boolean | False | Specifies whether client-side classes should be generated for each query, mutation and subscription. This includes: `Request` class (contains input data) and `ResponseProjection` class (contains response fields). | | `requestSuffix` | String | Request | Sets the suffix for `Request` classes. | | `responseProjectionSuffix` | String | ResponseProjection | Sets the suffix for `ResponseProjection` classes. | +| `parametrizedInputSuffix` | String | ParametrizedInput | Sets the suffix for `ParametrizedInput` classes. | | `parentInterfaces` | *See [parentInterfaces](#option-parentinterfaces)* | Empty | Block to define parent interfaces for generated interfaces (query / mutation / subscription / type resolver) | diff --git a/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java b/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java index 652d2ae24..7e25fe6aa 100644 --- a/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java +++ b/plugins/gradle/graphql-java-codegen-gradle-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/gradle/GraphQLCodegenGradleTask.java @@ -51,6 +51,7 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode private Boolean generateRequests; private String requestSuffix; private String responseProjectionSuffix; + private String parametrizedInputSuffix; private final ParentInterfacesConfig parentInterfaces = new ParentInterfacesConfig(); private String jsonConfigurationFile; @@ -84,6 +85,7 @@ public void generate() throws Exception { mappingConfig.setGenerateRequests(generateRequests); mappingConfig.setRequestSuffix(requestSuffix); mappingConfig.setResponseProjectionSuffix(responseProjectionSuffix); + mappingConfig.setParametrizedInputSuffix(parametrizedInputSuffix); mappingConfig.setResolverParentInterface(getResolverParentInterface()); mappingConfig.setQueryResolverParentInterface(getQueryResolverParentInterface()); mappingConfig.setMutationResolverParentInterface(getMutationResolverParentInterface()); @@ -408,6 +410,17 @@ public void setResponseProjectionSuffix(String responseProjectionSuffix) { this.responseProjectionSuffix = responseProjectionSuffix; } + @Input + @Optional + @Override + public String getParametrizedInputSuffix() { + return parametrizedInputSuffix; + } + + public void setParametrizedInputSuffix(String parametrizedInputSuffix) { + this.parametrizedInputSuffix = parametrizedInputSuffix; + } + @Nested @Optional public ParentInterfacesConfig getParentInterfaces() { diff --git a/plugins/maven/README.md b/plugins/maven/README.md index e7345fa4d..b58f1da32 100644 --- a/plugins/maven/README.md +++ b/plugins/maven/README.md @@ -94,6 +94,7 @@ You can run the plugin manually with `mvn generate-sources`. It will be run auto | `generateRequests` | Boolean | False | Specifies whether client-side classes should be generated for each query, mutation and subscription. This includes: `Request` class (contains input data) and `ResponseProjection` class (contains response fields). | | `requestSuffix` | String | Request | Sets the suffix for `Request` classes. | | `responseProjectionSuffix` | String | ResponseProjection | Sets the suffix for `ResponseProjection` classes. | +| `parametrizedInputSuffix` | String | ParametrizedInput | Sets the suffix for `ParametrizedInput` classes. | | `parentInterfaces` | *See [parentInterfaces](#option-parentinterfaces)* | Empty | Block to define parent interfaces for generated interfaces (query / mutation / subscription / type resolver) | diff --git a/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java b/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java index 7fec36660..2a2a85566 100644 --- a/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java +++ b/plugins/maven/graphql-java-codegen-maven-plugin/src/main/java/io/github/kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java @@ -99,6 +99,9 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo @Parameter(defaultValue = MappingConfigConstants.DEFAULT_RESPONSE_PROJECTION_SUFFIX) private String responseProjectionSuffix; + @Parameter(defaultValue = MappingConfigConstants.DEFAULT_PARAMETRIZED_INPUT_SUFIX) + private String parametrizedInputSuffix; + @Parameter private String jsonConfigurationFile; @@ -138,6 +141,7 @@ public void execute() throws MojoExecutionException { mappingConfig.setGenerateRequests(generateRequests); mappingConfig.setRequestSuffix(requestSuffix); mappingConfig.setResponseProjectionSuffix(responseProjectionSuffix); + mappingConfig.setParametrizedInputSuffix(parametrizedInputSuffix); mappingConfig.setResolverParentInterface(getResolverParentInterface()); mappingConfig.setQueryResolverParentInterface(getQueryResolverParentInterface()); mappingConfig.setMutationResolverParentInterface(getMutationResolverParentInterface()); @@ -409,6 +413,19 @@ public String getResponseProjectionSuffix() { return responseProjectionSuffix; } + public void setResponseProjectionSuffix(String responseProjectionSuffix) { + this.responseProjectionSuffix = responseProjectionSuffix; + } + + @Override + public String getParametrizedInputSuffix() { + return parametrizedInputSuffix; + } + + public void setParametrizedInputSuffix(String parametrizedInputSuffix) { + this.parametrizedInputSuffix = parametrizedInputSuffix; + } + public ParentInterfacesConfig getParentInterfaces() { return parentInterfaces; } @@ -437,10 +454,6 @@ public String getResolverParentInterface() { return parentInterfaces.getResolver(); } - public void setResponseProjectionSuffix(String responseProjectionSuffix) { - this.responseProjectionSuffix = responseProjectionSuffix; - } - public String getJsonConfigurationFile() { return jsonConfigurationFile; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/FreeMarkerTemplatesRegistry.java b/src/main/java/com/kobylynskyi/graphql/codegen/FreeMarkerTemplatesRegistry.java index 52cff4e04..8a6019a4c 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/FreeMarkerTemplatesRegistry.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/FreeMarkerTemplatesRegistry.java @@ -15,6 +15,7 @@ class FreeMarkerTemplatesRegistry { static Template requestTemplate; static Template interfaceTemplate; static Template operationsTemplate; + static Template parametrizedInputTemplate; static Template responseProjectionTemplate; static { @@ -32,6 +33,7 @@ class FreeMarkerTemplatesRegistry { requestTemplate = configuration.getTemplate("templates/javaClassGraphqlRequest.ftl"); interfaceTemplate = configuration.getTemplate("templates/javaClassGraphqlInterface.ftl"); operationsTemplate = configuration.getTemplate("templates/javaClassGraphqlOperations.ftl"); + parametrizedInputTemplate = configuration.getTemplate("templates/javaClassGraphqlParametrizedInput.ftl"); responseProjectionTemplate = configuration.getTemplate("templates/javaClassGraphqlResponseProjection.ftl"); } catch (IOException e) { throw new UnableToLoadFreeMarkerTemplateException(e); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java b/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java index 5d24e8f4e..336ad8b42 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/GraphQLCodegen.java @@ -6,6 +6,7 @@ import com.kobylynskyi.graphql.codegen.model.MappingContext; import com.kobylynskyi.graphql.codegen.model.definitions.*; import com.kobylynskyi.graphql.codegen.supplier.MappingConfigSupplier; +import com.kobylynskyi.graphql.codegen.utils.Utils; import graphql.language.FieldDefinition; import graphql.language.ScalarTypeExtensionDefinition; import lombok.Getter; @@ -64,6 +65,9 @@ private void initDefaultValues(MappingConfig mappingConfig) { if (mappingConfig.getResponseProjectionSuffix() == null) { mappingConfig.setResponseProjectionSuffix(MappingConfigConstants.DEFAULT_RESPONSE_PROJECTION_SUFFIX); } + if (mappingConfig.getParametrizedInputSuffix() == null) { + mappingConfig.setParametrizedInputSuffix(MappingConfigConstants.DEFAULT_PARAMETRIZED_INPUT_SUFIX); + } if (mappingConfig.getGenerateToString() == null) { mappingConfig.setGenerateToString(MappingConfigConstants.DEFAULT_TO_STRING); } @@ -179,6 +183,13 @@ private List generateType(MappingContext mappingContext, ExtendedObjectTyp if (Boolean.TRUE.equals(mappingConfig.getGenerateRequests())) { Map responseProjDataModel = TypeDefinitionToDataModelMapper.mapResponseProjection(mappingContext, definition); generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.responseProjectionTemplate, responseProjDataModel, outputDir)); + + for (ExtendedFieldDefinition fieldDefinition : definition.getFieldDefinitions()) { + if (!Utils.isEmpty(fieldDefinition.getInputValueDefinitions())) { + Map fieldProjDataModel = TypeDefinitionToDataModelMapper.mapParametrizedInput(mappingContext, fieldDefinition, definition); + generatedFiles.add(GraphQLCodegenFileCreator.generateFile(FreeMarkerTemplatesRegistry.parametrizedInputTemplate, fieldProjDataModel, outputDir)); + } + } } return generatedFiles; } 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 e08998352..0d7ca823f 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/FieldDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/FieldDefinitionToParameterMapper.java @@ -3,6 +3,7 @@ import com.kobylynskyi.graphql.codegen.model.MappingContext; import com.kobylynskyi.graphql.codegen.model.ParameterDefinition; import com.kobylynskyi.graphql.codegen.model.ProjectionParameterDefinition; +import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedFieldDefinition; import com.kobylynskyi.graphql.codegen.utils.Utils; @@ -38,14 +39,16 @@ public static List mapFields(MappingContext mappingContext, /** * Map field definition to a Freemarker-understandable data model type * - * @param mappingContext Global mapping context - * @param fieldDefinitions List of GraphQL field definitions + * @param mappingContext Global mapping context + * @param fieldDefinitions List of GraphQL field definitions + * @param parentTypeDefinition Parent GraphQL type definition * @return Freemarker data model of the GraphQL field definition */ public static List mapProjectionFields(MappingContext mappingContext, - List fieldDefinitions) { + List fieldDefinitions, + ExtendedDefinition parentTypeDefinition) { return fieldDefinitions.stream() - .map(fieldDef -> mapProjectionField(mappingContext, fieldDef)) + .map(fieldDef -> mapProjectionField(mappingContext, fieldDef, parentTypeDefinition)) .collect(toList()); } @@ -73,16 +76,22 @@ private static ParameterDefinition mapField(MappingContext mappingContext, Exten * * @param mappingContext Global mapping context * @param fieldDef GraphQL field definition + * @param parentTypeDef GraphQL definition which is a parent to provided field definition * @return Freemarker-understandable format of parameter (field) */ private static ProjectionParameterDefinition mapProjectionField(MappingContext mappingContext, - ExtendedFieldDefinition fieldDef) { + ExtendedFieldDefinition fieldDef, + ExtendedDefinition parentTypeDef) { ProjectionParameterDefinition parameter = new ProjectionParameterDefinition(); parameter.setName(MapperUtils.capitalizeIfRestricted(fieldDef.getName())); String nestedType = getNestedTypeName(fieldDef.getType()); if (mappingContext.getTypeNames().contains(nestedType)) { parameter.setType(nestedType + mappingContext.getResponseProjectionSuffix()); } + if (!Utils.isEmpty(fieldDef.getInputValueDefinitions())) { + parameter.setParametrizedInputClassName( + MapperUtils.getParametrizedInputClassName(mappingContext, fieldDef, parentTypeDef)); + } parameter.setDeprecated(fieldDef.isDeprecated()); return parameter; } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/MapperUtils.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/MapperUtils.java index 85128ec13..68c2a65aa 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/MapperUtils.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/MapperUtils.java @@ -68,6 +68,22 @@ static String getClassNameWithPrefixAndSuffix(MappingContext mappingContext, Str return classNameBuilder.toString(); } + /** + * Generates a class name for ParametrizedInput + * + * @param mappingContext Global mapping context + * @param fieldDefinition GraphQL field definition for a field that has parametrized input + * @param parentTypeDefinition GraphQL definition which is a parent for fieldDefinition + * @return Class name of parametrized input + */ + static String getParametrizedInputClassName(MappingContext mappingContext, + ExtendedFieldDefinition fieldDefinition, + ExtendedDefinition parentTypeDefinition) { + return Utils.capitalize(parentTypeDefinition.getName()) + + Utils.capitalize(fieldDefinition.getName()) + + mappingContext.getParametrizedInputSuffix(); + } + /** * Get java package name for api class. * diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/TypeDefinitionToDataModelMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/TypeDefinitionToDataModelMapper.java index b68ac2498..1a810cebe 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/TypeDefinitionToDataModelMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/TypeDefinitionToDataModelMapper.java @@ -4,6 +4,7 @@ import com.kobylynskyi.graphql.codegen.model.ParameterDefinition; import com.kobylynskyi.graphql.codegen.model.ProjectionParameterDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDocument; +import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedFieldDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedInterfaceTypeDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedObjectTypeDefinition; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedUnionTypeDefinition; @@ -68,6 +69,31 @@ public static Map mapResponseProjection(MappingContext mappingCo return dataModel; } + /** + * Map field definition to a Freemarker data model of Parametrized Input. + * + * @param mappingContext Global mapping context + * @param fieldDefinition GraphQL field definition + * @param parentTypeDefinition GraphQL parent type definition + * @return Freemarker data model of the GraphQL Parametrized Input + */ + public static Map mapParametrizedInput(MappingContext mappingContext, + ExtendedFieldDefinition fieldDefinition, + ExtendedObjectTypeDefinition parentTypeDefinition) { + Map dataModel = new HashMap<>(); + // ParametrizedInput classes are sharing the package with the model classes, so no imports are needed + dataModel.put(PACKAGE, MapperUtils.getModelPackageName(mappingContext)); + dataModel.put(CLASS_NAME, MapperUtils.getParametrizedInputClassName(mappingContext, fieldDefinition, parentTypeDefinition)); + dataModel.put(JAVA_DOC, Collections.singletonList(String.format("Parametrized input for field %s in type %s", + fieldDefinition.getName(), parentTypeDefinition.getName()))); + dataModel.put(FIELDS, InputValueDefinitionToParameterMapper.map( + mappingContext, fieldDefinition.getInputValueDefinitions(), parentTypeDefinition.getName())); + dataModel.put(BUILDER, mappingContext.getGenerateBuilder()); + dataModel.put(EQUALS_AND_HASH_CODE, mappingContext.getGenerateEqualsAndHashCode()); + // dataModel.put(TO_STRING, mappingConfig.getGenerateToString()); always generated for serialization purposes + return dataModel; + } + /** * Get merged attributes from the type and attributes from the interface. * @@ -124,11 +150,11 @@ private static Collection getProjectionFields(Map Map allParameters = new LinkedHashMap<>(); // includes parameters from the base definition and extensions - FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, typeDefinition.getFieldDefinitions()) + FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, typeDefinition.getFieldDefinitions(), typeDefinition) .forEach(p -> allParameters.put(p.getName(), p)); // includes parameters from the interface getInterfacesOfType(typeDefinition, mappingContext.getDocument()).stream() - .map(i -> FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, i.getFieldDefinitions())) + .map(i -> FieldDefinitionToParameterMapper.mapProjectionFields(mappingContext, i.getFieldDefinitions(), i)) .flatMap(Collection::stream) .filter(paramDef -> !allParameters.containsKey(paramDef.getName())) .forEach(paramDef -> allParameters.put(paramDef.getName(), paramDef)); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java index 7dbd1607c..042195902 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java @@ -192,6 +192,13 @@ public interface GraphQLCodegenConfiguration { */ String getResponseProjectionSuffix(); + /** + * The suffix for `ParametrizedInput` classes. + * + * @return The suffix for `ParametrizedInput` classes. + */ + String getParametrizedInputSuffix(); + /** * Interface that will be added as "extend" to all generated api Query interfaces. * diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java index c15269aa7..67e67c9de 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java @@ -44,6 +44,7 @@ public class MappingConfig implements GraphQLCodegenConfiguration, Combinable fields = new LinkedHashMap<>(); + protected final Map parametrizedInputs = new LinkedHashMap<>(); + + @Override + public String toString() { + if (fields.isEmpty()) { + return ""; + } + StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); + for (Map.Entry property : fields.entrySet()) { + joiner.add(property.getKey()); + GraphQLParametrizedInput parametrizedInput = parametrizedInputs.get(property.getKey()); + if (parametrizedInput != null) { + joiner.add(parametrizedInput.toString()); + } + if (property.getValue() != null) { + joiner.add(" ").add(property.getValue().toString()); + } + } + return joiner.toString(); + } } diff --git a/src/main/resources/templates/javaClassGraphqlParametrizedInput.ftl b/src/main/resources/templates/javaClassGraphqlParametrizedInput.ftl new file mode 100644 index 000000000..7de86e252 --- /dev/null +++ b/src/main/resources/templates/javaClassGraphqlParametrizedInput.ftl @@ -0,0 +1,96 @@ +<#if package?has_content> +package ${package}; + + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLParametrizedInput; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; +import java.util.StringJoiner; +<#if equalsAndHashCode> +import java.util.Objects; + + +<#if javaDoc?has_content> +/** +<#list javaDoc as javaDocLine> + * ${javaDocLine} + + */ + +public class ${className} implements GraphQLParametrizedInput { + +<#list fields as field> +<#if field.deprecated> + @Deprecated + +<#list field.annotations as annotation> + @${annotation} + + private ${field.type} ${field.name}<#if field.defaultValue?has_content> = ${field.defaultValue}; + + + public ${className}() { + } + +<#if fields?has_content> + public ${className}(<#list fields as field>${field.type} ${field.name}<#if field_has_next>, ) { +<#list fields as field> + this.${field.name} = ${field.name}; + + } + + +<#list fields as field> +<#if field.javaDoc?has_content> + /** +<#list field.javaDoc as javaDocLine> + * ${javaDocLine} + + */ + +<#if field.deprecated> + @Deprecated + + public ${className} ${field.name}(${field.type} ${field.name}) { + this.${field.name} = ${field.name}; + return this; + } + + +<#if equalsAndHashCode> + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final ${className} that = (${className}) obj; + return <#list fields as field>Objects.equals(${field.name}, that.${field.name})<#if field_has_next> + && ; + } + + @Override + public int hashCode() { +<#if fields?has_content> + return Objects.hash(<#list fields as field>${field.name}<#if field_has_next>, ); +<#else> + return 0; + + } + + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "(", ")"); +<#if fields?has_content> +<#list fields as field> + if (${field.name} != null) { + joiner.add("${field.name}: " + GraphQLRequestSerializer.getEntry(${field.name})); + } + + + return joiner.toString(); + } + +} diff --git a/src/main/resources/templates/javaClassGraphqlResponseProjection.ftl b/src/main/resources/templates/javaClassGraphqlResponseProjection.ftl index 87388b85f..792b43e2b 100644 --- a/src/main/resources/templates/javaClassGraphqlResponseProjection.ftl +++ b/src/main/resources/templates/javaClassGraphqlResponseProjection.ftl @@ -3,10 +3,9 @@ package ${package}; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.LinkedHashMap; -import java.util.Map; +<#if equalsAndHashCode> import java.util.Objects; -import java.util.StringJoiner; + <#if javaDoc?has_content> /** @@ -15,9 +14,7 @@ import java.util.StringJoiner; */ -public class ${className} implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class ${className} extends GraphQLResponseProjection { public ${className}() { } @@ -38,6 +35,13 @@ public class ${className} implements GraphQLResponseProjection { return this; } +<#if field.parametrizedInputClassName?has_content> + public ${className} ${field.name}(${field.parametrizedInputClassName} input<#if field.type?has_content>, ${field.type} subProjection) { + parametrizedInputs.put("${field.name}", input); + return ${field.name}(<#if field.type?has_content>subProjection); + } + + <#if equalsAndHashCode> @Override @@ -49,27 +53,13 @@ public class ${className} implements GraphQLResponseProjection { return false; } final ${className} that = (${className}) obj; - return Objects.equals(fields, that.fields); + return Objects.equals(fields, that.fields) && Objects.equals(parametrizedInputs, that.parametrizedInputs); } @Override public int hashCode() { - return Objects.hash(fields); + return Objects.hash(fields, parametrizedInputs); } - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; - } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } - } - return joiner.toString(); - } } diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenRequestTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenRequestTest.java index 4918cf108..181749ab3 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenRequestTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenRequestTest.java @@ -27,6 +27,7 @@ void init() { mappingConfig.setResponseProjectionSuffix("ResponseProjection"); mappingConfig.setRequestSuffix("Request"); mappingConfig.setGenerateRequests(true); + mappingConfig.setGenerateEqualsAndHashCode(true); mappingConfig.setGenerateToString(false); // should be overridden to true mappingConfig.setGenerateApis(false); } @@ -47,6 +48,10 @@ void generate_RequestAndResponseProjections() throws Exception { getFileByName(files, "EventResponseProjection.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/EventPropertyResponseProjection.java.txt"), getFileByName(files, "EventPropertyResponseProjection.java")); + assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput.java.txt"), + getFileByName(files, "EventPropertyParentParametrizedInput.java")); + assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/EventPropertyChildParametrizedInput.java.txt"), + getFileByName(files, "EventPropertyChildParametrizedInput.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest.java.txt"), getFileByName(files, "EventsByCategoryAndStatusQueryRequest.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/VersionQueryRequest.java.txt"), @@ -67,6 +72,8 @@ void generate_WithModelSuffix() throws Exception { getFileByName(files, "EventStatusTO.java")); assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withModelSuffix.java.txt"), getFileByName(files, "EventsByCategoryAndStatusQueryRequest.java")); + assertSameTrimmedContent(new File("src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput_withModelSuffix.java.txt"), + getFileByName(files, "EventPropertyParentParametrizedInput.java")); } @Test diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java index 2938fc9d1..a9446febb 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenTest.java @@ -35,12 +35,13 @@ class GraphQLCodegenTest { void init() { mappingConfig = new MappingConfig(); mappingConfig.setPackageName("com.kobylynskyi.graphql.test1"); + mappingConfig.setGenerateParameterizedFieldsResolvers(false); generator = new GraphQLCodegen(singletonList("src/test/resources/schemas/test.graphqls"), outputBuildDir, mappingConfig); } @AfterEach - void cleanup() throws IOException { + void cleanup() { Utils.deleteDir(new File("build/generated")); } diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/MappingConfigTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/MappingConfigTest.java index d23dfa723..d0f65968b 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/MappingConfigTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/MappingConfigTest.java @@ -80,6 +80,7 @@ void combineCustomWithDefault() { assertEquals("6", mappingConfig.getRequestSuffix()); assertEquals("7", mappingConfig.getResponseProjectionSuffix()); assertFalse(mappingConfig.getGenerateRequests()); + assertEquals("9", mappingConfig.getParametrizedInputSuffix()); } @Test @@ -110,6 +111,7 @@ void combineCustomWithCustom() { assertEquals("66", mappingConfig.getRequestSuffix()); assertEquals("77", mappingConfig.getResponseProjectionSuffix()); assertTrue(mappingConfig.getGenerateRequests()); + assertEquals("99", mappingConfig.getParametrizedInputSuffix()); } private static Map hashMap(AbstractMap.SimpleEntry... entries) { @@ -140,6 +142,7 @@ private static MappingConfig buildMappingConfig() { config.setRequestSuffix("6"); config.setResponseProjectionSuffix("7"); config.setGenerateRequests(false); + config.setParametrizedInputSuffix("9"); return config; } @@ -166,6 +169,7 @@ private static MappingConfig buildMappingConfig2() { config.setRequestSuffix("66"); config.setResponseProjectionSuffix("77"); config.setGenerateRequests(true); + config.setParametrizedInputSuffix("99"); return config; } diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java index 52b01d5b7..b2554f68d 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/GraphQLRequestSerializerTest.java @@ -58,6 +58,42 @@ void serialize_withResponseProjection() { "}"), serializedQuery); } + @Test + void serialize_withResponseProjectionAndParametrizedInput() { + EventsByCategoryAndStatusQueryRequest request = new EventsByCategoryAndStatusQueryRequest.Builder() + .setCategoryId("categoryIdValue1") + .setStatus(Status.OPEN) + .build(); + GraphQLRequest graphQLRequest = new GraphQLRequest(request, + new EventResponseProjection() + .id() + .active() + .properties(new EventPropertyResponseProjection() + .floatVal() + .child(new EventPropertyChildParametrizedInput() + .last(-10) + .first(+10), + new EventPropertyResponseProjection() + .intVal() + .parent(new EventPropertyParentParametrizedInput() + .withStatus(Status.OPEN), + new EventResponseProjection() + .id())) + .booleanVal()) + .status() + ); + String serializedQuery = graphQLRequest.toString().replaceAll(" +", " ").trim(); + assertEquals(expected("query { " + + "eventsByCategoryAndStatus(categoryId: \\\"categoryIdValue1\\\", status: OPEN){ " + + "id " + + "active " + + "properties { " + + "floatVal child (first: 10, last: -10) { intVal parent (withStatus: OPEN) { id } } booleanVal } " + + "status " + + "} " + + "}"), serializedQuery); + } + @Test void serialize_complexRequestWithDefaultData() { UpdateIssueMutationRequest requestWithDefaultData = new UpdateIssueMutationRequest(); diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyChildParametrizedInput.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyChildParametrizedInput.java new file mode 100644 index 000000000..b8a4f6f26 --- /dev/null +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyChildParametrizedInput.java @@ -0,0 +1,65 @@ +package com.kobylynskyi.graphql.codegen.model.graphql.data; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLParametrizedInput; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; + +import java.util.Objects; +import java.util.StringJoiner; + +/** + * Parametrized input for field child in type EventProperty + */ +public class EventPropertyChildParametrizedInput implements GraphQLParametrizedInput { + + private Integer first; + private Integer last; + + public EventPropertyChildParametrizedInput() { + } + + public EventPropertyChildParametrizedInput(Integer first, Integer last) { + this.first = first; + this.last = last; + } + + public EventPropertyChildParametrizedInput first(Integer first) { + this.first = first; + return this; + } + + public EventPropertyChildParametrizedInput last(Integer last) { + this.last = last; + return this; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventPropertyChildParametrizedInput that = (EventPropertyChildParametrizedInput) obj; + return Objects.equals(first, that.first) + && Objects.equals(last, that.last); + } + + @Override + public int hashCode() { + return Objects.hash(first, last); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "(", ")"); + if (first != null) { + joiner.add("first: " + GraphQLRequestSerializer.getEntry(first)); + } + if (last != null) { + joiner.add("last: " + GraphQLRequestSerializer.getEntry(last)); + } + return joiner.toString(); + } + +} \ No newline at end of file diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyParentParametrizedInput.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyParentParametrizedInput.java new file mode 100644 index 000000000..a8aff5798 --- /dev/null +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyParentParametrizedInput.java @@ -0,0 +1,54 @@ +package com.kobylynskyi.graphql.codegen.model.graphql.data; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLParametrizedInput; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; + +import java.util.Objects; +import java.util.StringJoiner; + +/** + * Parametrized input for field parent in type EventProperty + */ +public class EventPropertyParentParametrizedInput implements GraphQLParametrizedInput { + + private Status withStatus; + + public EventPropertyParentParametrizedInput() { + } + + public EventPropertyParentParametrizedInput(Status withStatus) { + this.withStatus = withStatus; + } + + public EventPropertyParentParametrizedInput withStatus(Status withStatus) { + this.withStatus = withStatus; + return this; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventPropertyParentParametrizedInput that = (EventPropertyParentParametrizedInput) obj; + return Objects.equals(withStatus, that.withStatus); + } + + @Override + public int hashCode() { + return Objects.hash(withStatus); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "(", ")"); + if (withStatus != null) { + joiner.add("withStatus: " + GraphQLRequestSerializer.getEntry(withStatus)); + } + return joiner.toString(); + } + +} \ No newline at end of file diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyResponseProjection.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyResponseProjection.java index e21b8547f..09bb71d8d 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyResponseProjection.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventPropertyResponseProjection.java @@ -6,9 +6,10 @@ import java.util.Map; import java.util.StringJoiner; -public class EventPropertyResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +/** + * Response projection for EventProperty + */ +public class EventPropertyResponseProjection extends GraphQLResponseProjection { public EventPropertyResponseProjection() { } @@ -38,24 +39,19 @@ public EventPropertyResponseProjection child(EventPropertyResponseProjection sub return this; } + public EventPropertyResponseProjection child(EventPropertyChildParametrizedInput input, EventPropertyResponseProjection subProjection) { + parametrizedInputs.put("child", input); + return child(subProjection); + } + public EventPropertyResponseProjection parent(EventResponseProjection subProjection) { fields.put("parent", subProjection); return this; } - - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; - } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } - } - return joiner.toString(); + public EventPropertyResponseProjection parent(EventPropertyParentParametrizedInput input, EventResponseProjection subProjection) { + parametrizedInputs.put("parent", input); + return parent(subProjection); } + } \ No newline at end of file diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventResponseProjection.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventResponseProjection.java index 636fd7eb2..2fbb332f3 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventResponseProjection.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/EventResponseProjection.java @@ -2,11 +2,13 @@ import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.*; +import java.util.Map; +import java.util.StringJoiner; -public class EventResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +/** + * Response projection for Event + */ +public class EventResponseProjection extends GraphQLResponseProjection { public EventResponseProjection() { } @@ -51,19 +53,4 @@ public EventResponseProjection rating() { return this; } - - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; - } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } - } - return joiner.toString(); - } } \ No newline at end of file diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/IssueResponseProjection.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/IssueResponseProjection.java index 17acb52da..97505b758 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/IssueResponseProjection.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/IssueResponseProjection.java @@ -2,13 +2,7 @@ import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.StringJoiner; - -public class IssueResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class IssueResponseProjection extends GraphQLResponseProjection { public IssueResponseProjection() { } @@ -20,18 +14,4 @@ public IssueResponseProjection activeLockReason() { // REST OF THE STUFF WAS REMOVED - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; - } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } - } - return joiner.toString(); - } } diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/UpdateIssuePayloadResponseProjection.java b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/UpdateIssuePayloadResponseProjection.java index 0d97644e7..e666a45ca 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/UpdateIssuePayloadResponseProjection.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/model/graphql/data/UpdateIssuePayloadResponseProjection.java @@ -2,11 +2,7 @@ import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.*; - -public class UpdateIssuePayloadResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class UpdateIssuePayloadResponseProjection extends GraphQLResponseProjection { public UpdateIssuePayloadResponseProjection() { } @@ -21,19 +17,4 @@ public UpdateIssuePayloadResponseProjection issue(IssueResponseProjection subPro return this; } - - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; - } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } - } - return joiner.toString(); - } } diff --git a/src/test/resources/expected-classes/extend/request/AssetResponseProjection.java.txt b/src/test/resources/expected-classes/extend/request/AssetResponseProjection.java.txt index 3cb872d93..3d0c2df50 100644 --- a/src/test/resources/expected-classes/extend/request/AssetResponseProjection.java.txt +++ b/src/test/resources/expected-classes/extend/request/AssetResponseProjection.java.txt @@ -1,15 +1,9 @@ import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.StringJoiner; /** * Response projection for Asset */ -public class AssetResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class AssetResponseProjection extends GraphQLResponseProjection { public AssetResponseProjection() { } @@ -35,18 +29,4 @@ public class AssetResponseProjection implements GraphQLResponseProjection { } - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; - } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } - } - return joiner.toString(); - } -} +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/extend/request/EventResponseProjection.java.txt b/src/test/resources/expected-classes/extend/request/EventResponseProjection.java.txt index 372708e04..3eb884298 100644 --- a/src/test/resources/expected-classes/extend/request/EventResponseProjection.java.txt +++ b/src/test/resources/expected-classes/extend/request/EventResponseProjection.java.txt @@ -1,15 +1,9 @@ import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.StringJoiner; /** * Response projection for Event */ -public class EventResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class EventResponseProjection extends GraphQLResponseProjection { public EventResponseProjection() { } @@ -40,18 +34,4 @@ public class EventResponseProjection implements GraphQLResponseProjection { } - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; - } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } - } - return joiner.toString(); - } } \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/AcceptTopicSuggestionInput.java.txt b/src/test/resources/expected-classes/request/AcceptTopicSuggestionInput.java.txt index 35a0fd8ee..a2f6f16fb 100644 --- a/src/test/resources/expected-classes/request/AcceptTopicSuggestionInput.java.txt +++ b/src/test/resources/expected-classes/request/AcceptTopicSuggestionInput.java.txt @@ -1,6 +1,7 @@ package com.github.graphql; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; +import java.util.Objects; import java.util.StringJoiner; public class AcceptTopicSuggestionInput { @@ -41,6 +42,24 @@ public class AcceptTopicSuggestionInput { this.repositoryId = repositoryId; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final AcceptTopicSuggestionInput that = (AcceptTopicSuggestionInput) obj; + return Objects.equals(clientMutationId, that.clientMutationId) + && Objects.equals(name, that.name) + && Objects.equals(repositoryId, that.repositoryId); + } + + @Override + public int hashCode() { + return Objects.hash(clientMutationId, name, repositoryId); + } @Override public String toString() { diff --git a/src/test/resources/expected-classes/request/CodeOfConductResponseProjection.java.txt b/src/test/resources/expected-classes/request/CodeOfConductResponseProjection.java.txt index 74a72ae01..34f7ce851 100644 --- a/src/test/resources/expected-classes/request/CodeOfConductResponseProjection.java.txt +++ b/src/test/resources/expected-classes/request/CodeOfConductResponseProjection.java.txt @@ -1,17 +1,12 @@ package com.github.graphql; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Objects; -import java.util.StringJoiner; /** * Response projection for CodeOfConduct */ -public class CodeOfConductResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class CodeOfConductResponseProjection extends GraphQLResponseProjection { public CodeOfConductResponseProjection() { } @@ -46,19 +41,21 @@ public class CodeOfConductResponseProjection implements GraphQLResponseProjectio return this; } - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; + public boolean equals(Object obj) { + if (this == obj) { + return true; } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } + if (obj == null || getClass() != obj.getClass()) { + return false; } - return joiner.toString(); + final CodeOfConductResponseProjection that = (CodeOfConductResponseProjection) obj; + return Objects.equals(fields, that.fields) && Objects.equals(parametrizedInputs, that.parametrizedInputs); + } + + @Override + public int hashCode() { + return Objects.hash(fields, parametrizedInputs); } + } \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/EventPropertyChildParametrizedInput.java.txt b/src/test/resources/expected-classes/request/EventPropertyChildParametrizedInput.java.txt new file mode 100644 index 000000000..3778d4ea5 --- /dev/null +++ b/src/test/resources/expected-classes/request/EventPropertyChildParametrizedInput.java.txt @@ -0,0 +1,64 @@ +package com.github.graphql; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLParametrizedInput; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; +import java.util.StringJoiner; +import java.util.Objects; + +/** + * Parametrized input for field child in type EventProperty + */ +public class EventPropertyChildParametrizedInput implements GraphQLParametrizedInput { + + private Integer first; + private Integer last; + + public EventPropertyChildParametrizedInput() { + } + + public EventPropertyChildParametrizedInput(Integer first, Integer last) { + this.first = first; + this.last = last; + } + + public EventPropertyChildParametrizedInput first(Integer first) { + this.first = first; + return this; + } + + public EventPropertyChildParametrizedInput last(Integer last) { + this.last = last; + return this; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventPropertyChildParametrizedInput that = (EventPropertyChildParametrizedInput) obj; + return Objects.equals(first, that.first) + && Objects.equals(last, that.last); + } + + @Override + public int hashCode() { + return Objects.hash(first, last); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "(", ")"); + if (first != null) { + joiner.add("first: " + GraphQLRequestSerializer.getEntry(first)); + } + if (last != null) { + joiner.add("last: " + GraphQLRequestSerializer.getEntry(last)); + } + return joiner.toString(); + } + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput.java.txt b/src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput.java.txt new file mode 100644 index 000000000..da871e27f --- /dev/null +++ b/src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput.java.txt @@ -0,0 +1,53 @@ +package com.github.graphql; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLParametrizedInput; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; +import java.util.StringJoiner; +import java.util.Objects; + +/** + * Parametrized input for field parent in type EventProperty + */ +public class EventPropertyParentParametrizedInput implements GraphQLParametrizedInput { + + private EventStatus withStatus; + + public EventPropertyParentParametrizedInput() { + } + + public EventPropertyParentParametrizedInput(EventStatus withStatus) { + this.withStatus = withStatus; + } + + public EventPropertyParentParametrizedInput withStatus(EventStatus withStatus) { + this.withStatus = withStatus; + return this; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventPropertyParentParametrizedInput that = (EventPropertyParentParametrizedInput) obj; + return Objects.equals(withStatus, that.withStatus); + } + + @Override + public int hashCode() { + return Objects.hash(withStatus); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "(", ")"); + if (withStatus != null) { + joiner.add("withStatus: " + GraphQLRequestSerializer.getEntry(withStatus)); + } + return joiner.toString(); + } + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput_withModelSuffix.java.txt b/src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput_withModelSuffix.java.txt new file mode 100644 index 000000000..10ffdd952 --- /dev/null +++ b/src/test/resources/expected-classes/request/EventPropertyParentParametrizedInput_withModelSuffix.java.txt @@ -0,0 +1,53 @@ +package com.github.graphql; + +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLParametrizedInput; +import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLRequestSerializer; +import java.util.StringJoiner; +import java.util.Objects; + +/** + * Parametrized input for field parent in type EventProperty + */ +public class EventPropertyParentParametrizedInput implements GraphQLParametrizedInput { + + private EventStatusTO withStatus; + + public EventPropertyParentParametrizedInput() { + } + + public EventPropertyParentParametrizedInput(EventStatusTO withStatus) { + this.withStatus = withStatus; + } + + public EventPropertyParentParametrizedInput withStatus(EventStatusTO withStatus) { + this.withStatus = withStatus; + return this; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventPropertyParentParametrizedInput that = (EventPropertyParentParametrizedInput) obj; + return Objects.equals(withStatus, that.withStatus); + } + + @Override + public int hashCode() { + return Objects.hash(withStatus); + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner(", ", "(", ")"); + if (withStatus != null) { + joiner.add("withStatus: " + GraphQLRequestSerializer.getEntry(withStatus)); + } + return joiner.toString(); + } + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/EventPropertyResponseProjection.java.txt b/src/test/resources/expected-classes/request/EventPropertyResponseProjection.java.txt index f33fbc8ca..85fa9c7af 100644 --- a/src/test/resources/expected-classes/request/EventPropertyResponseProjection.java.txt +++ b/src/test/resources/expected-classes/request/EventPropertyResponseProjection.java.txt @@ -1,17 +1,12 @@ package com.github.graphql; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Objects; -import java.util.StringJoiner; /** * Response projection for EventProperty */ -public class EventPropertyResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class EventPropertyResponseProjection extends GraphQLResponseProjection { public EventPropertyResponseProjection() { } @@ -41,24 +36,36 @@ public class EventPropertyResponseProjection implements GraphQLResponseProjectio return this; } + public EventPropertyResponseProjection child(EventPropertyChildParametrizedInput input, EventPropertyResponseProjection subProjection) { + parametrizedInputs.put("child", input); + return child(subProjection); + } + public EventPropertyResponseProjection parent(EventResponseProjection subProjection) { fields.put("parent", subProjection); return this; } + public EventPropertyResponseProjection parent(EventPropertyParentParametrizedInput input, EventResponseProjection subProjection) { + parametrizedInputs.put("parent", input); + return parent(subProjection); + } @Override - public String toString() { - if (fields.isEmpty()) { - return ""; + public boolean equals(Object obj) { + if (this == obj) { + return true; } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } + if (obj == null || getClass() != obj.getClass()) { + return false; } - return joiner.toString(); + final EventPropertyResponseProjection that = (EventPropertyResponseProjection) obj; + return Objects.equals(fields, that.fields) && Objects.equals(parametrizedInputs, that.parametrizedInputs); } + + @Override + public int hashCode() { + return Objects.hash(fields, parametrizedInputs); + } + } \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/EventResponseProjection.java.txt b/src/test/resources/expected-classes/request/EventResponseProjection.java.txt index 5a4a3e932..024851e32 100644 --- a/src/test/resources/expected-classes/request/EventResponseProjection.java.txt +++ b/src/test/resources/expected-classes/request/EventResponseProjection.java.txt @@ -1,17 +1,12 @@ package com.github.graphql; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLResponseProjection; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Objects; -import java.util.StringJoiner; /** * Response projection for Event */ -public class EventResponseProjection implements GraphQLResponseProjection { - - private Map fields = new LinkedHashMap<>(); +public class EventResponseProjection extends GraphQLResponseProjection { public EventResponseProjection() { } @@ -56,19 +51,21 @@ public class EventResponseProjection implements GraphQLResponseProjection { return this; } - @Override - public String toString() { - if (fields.isEmpty()) { - return ""; + public boolean equals(Object obj) { + if (this == obj) { + return true; } - StringJoiner joiner = new StringJoiner(" ", "{ ", " }"); - for (Map.Entry property : fields.entrySet()) { - joiner.add(property.getKey()); - if (property.getValue() != null) { - joiner.add(" ").add(property.getValue().toString()); - } + if (obj == null || getClass() != obj.getClass()) { + return false; } - return joiner.toString(); + final EventResponseProjection that = (EventResponseProjection) obj; + return Objects.equals(fields, that.fields) && Objects.equals(parametrizedInputs, that.parametrizedInputs); + } + + @Override + public int hashCode() { + return Objects.hash(fields, parametrizedInputs); } + } \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest.java.txt b/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest.java.txt index f5934d1c4..b691ca6e6 100644 --- a/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest.java.txt +++ b/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest.java.txt @@ -42,6 +42,24 @@ public class EventsByCategoryAndStatusQueryRequest implements GraphQLOperationRe return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventsByCategoryAndStatusQueryRequest that = (EventsByCategoryAndStatusQueryRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); diff --git a/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withApiImport.java.txt b/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withApiImport.java.txt index f5934d1c4..b691ca6e6 100644 --- a/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withApiImport.java.txt +++ b/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withApiImport.java.txt @@ -42,6 +42,24 @@ public class EventsByCategoryAndStatusQueryRequest implements GraphQLOperationRe return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventsByCategoryAndStatusQueryRequest that = (EventsByCategoryAndStatusQueryRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); diff --git a/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withModelSuffix.java.txt b/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withModelSuffix.java.txt index 3244382d4..c303a269b 100644 --- a/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withModelSuffix.java.txt +++ b/src/test/resources/expected-classes/request/EventsByCategoryAndStatusQueryRequest_withModelSuffix.java.txt @@ -42,6 +42,24 @@ public class EventsByCategoryAndStatusQueryRequest implements GraphQLOperationRe return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventsByCategoryAndStatusQueryRequest that = (EventsByCategoryAndStatusQueryRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); diff --git a/src/test/resources/expected-classes/request/EventsByIdsQueryRequest.java.txt b/src/test/resources/expected-classes/request/EventsByIdsQueryRequest.java.txt index d2a2333b6..292a5ed5a 100644 --- a/src/test/resources/expected-classes/request/EventsByIdsQueryRequest.java.txt +++ b/src/test/resources/expected-classes/request/EventsByIdsQueryRequest.java.txt @@ -38,6 +38,24 @@ public class EventsByIdsQueryRequest implements GraphQLOperationRequest { return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final EventsByIdsQueryRequest that = (EventsByIdsQueryRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); diff --git a/src/test/resources/expected-classes/request/ProductsByCategoryIdAndStatusQueryRequest.java.txt b/src/test/resources/expected-classes/request/ProductsByCategoryIdAndStatusQueryRequest.java.txt index e30b1d5e3..c8c43e44b 100644 --- a/src/test/resources/expected-classes/request/ProductsByCategoryIdAndStatusQueryRequest.java.txt +++ b/src/test/resources/expected-classes/request/ProductsByCategoryIdAndStatusQueryRequest.java.txt @@ -39,6 +39,24 @@ public class ProductsByCategoryIdAndStatusQueryRequest implements GraphQLOperati return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final ProductsByCategoryIdAndStatusQueryRequest that = (ProductsByCategoryIdAndStatusQueryRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); @@ -71,4 +89,4 @@ public class ProductsByCategoryIdAndStatusQueryRequest implements GraphQLOperati } } -} +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/ProductsByIdsQueryRequest.java.txt b/src/test/resources/expected-classes/request/ProductsByIdsQueryRequest.java.txt index 647dd9eae..cf1291133 100644 --- a/src/test/resources/expected-classes/request/ProductsByIdsQueryRequest.java.txt +++ b/src/test/resources/expected-classes/request/ProductsByIdsQueryRequest.java.txt @@ -35,6 +35,24 @@ public class ProductsByIdsQueryRequest implements GraphQLOperationRequest { return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final ProductsByIdsQueryRequest that = (ProductsByIdsQueryRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); @@ -60,4 +78,4 @@ public class ProductsByIdsQueryRequest implements GraphQLOperationRequest { } } -} +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/request/UpdateRepositoryMutationRequest.java.txt b/src/test/resources/expected-classes/request/UpdateRepositoryMutationRequest.java.txt index 11fa092df..809e1d3ec 100644 --- a/src/test/resources/expected-classes/request/UpdateRepositoryMutationRequest.java.txt +++ b/src/test/resources/expected-classes/request/UpdateRepositoryMutationRequest.java.txt @@ -35,6 +35,24 @@ public class UpdateRepositoryMutationRequest implements GraphQLOperationRequest return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final UpdateRepositoryMutationRequest that = (UpdateRepositoryMutationRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); diff --git a/src/test/resources/expected-classes/request/VersionQueryRequest.java.txt b/src/test/resources/expected-classes/request/VersionQueryRequest.java.txt index c8f9b4fbc..6a803e556 100644 --- a/src/test/resources/expected-classes/request/VersionQueryRequest.java.txt +++ b/src/test/resources/expected-classes/request/VersionQueryRequest.java.txt @@ -34,6 +34,24 @@ public class VersionQueryRequest implements GraphQLOperationRequest { return input; } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + final VersionQueryRequest that = (VersionQueryRequest) obj; + return Objects.equals(getOperationType(), that.getOperationType()) && + Objects.equals(getOperationName(), that.getOperationName()) && + Objects.equals(input, that.input); + } + + @Override + public int hashCode() { + return Objects.hash(getOperationType(), getOperationName(), input); + } @Override public String toString() { return Objects.toString(input); diff --git a/src/test/resources/schemas/test.graphqls b/src/test/resources/schemas/test.graphqls index ee9ce5e4f..ea4e9de6e 100644 --- a/src/test/resources/schemas/test.graphqls +++ b/src/test/resources/schemas/test.graphqls @@ -62,9 +62,9 @@ type EventProperty { # String comment stringVal: String # Properties - child: [EventProperty] + child(first: Int, last: Int): [EventProperty] # Parent event of the property - parent: Event + parent(withStatus: EventStatus): Event } # Custom DateTime scalar