From 7b443cc29477ffa74307e249ec5e0cdec0326fd1 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Thu, 11 Jan 2024 13:51:21 +0100 Subject: [PATCH 01/18] optional POC --- .java-version | 1 + ...InputValueDefinitionToParameterMapper.java | 34 +++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 .java-version diff --git a/.java-version b/.java-version new file mode 100644 index 000000000..625934097 --- /dev/null +++ b/.java-version @@ -0,0 +1 @@ +1.8 diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java index 61c14b686..5f181b083 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java @@ -5,9 +5,10 @@ import com.kobylynskyi.graphql.codegen.model.ParameterDefinition; import com.kobylynskyi.graphql.codegen.model.builders.DeprecatedDefinitionBuilder; import com.kobylynskyi.graphql.codegen.utils.Utils; -import graphql.language.InputValueDefinition; +import graphql.language.*; import java.util.List; +import java.util.Optional; import static java.util.stream.Collectors.toList; @@ -17,7 +18,8 @@ * @author kobylynskyi */ public class InputValueDefinitionToParameterMapper { - + private static final String JAVA_UTIL_OPTIONAL = "java.util.Optional"; + private static final String JAVA_UTIL_LIST = "java.util.List"; private final ValueMapper valueMapper; private final GraphQLTypeMapper graphQLTypeMapper; private final AnnotationsMapper annotationsMapper; @@ -62,10 +64,8 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit ParameterDefinition parameter = new ParameterDefinition(); parameter.setName(dataModelMapper.capitalizeIfRestricted(mappingContext, inputValueDefinition.getName())); parameter.setOriginalName(inputValueDefinition.getName()); - parameter.setType(graphQLTypeMapper.getTypeConsideringPrimitive(mappingContext, namedDefinition, - namedDefinition.getJavaName())); - parameter.setDefaultValue(valueMapper.map( - mappingContext, inputValueDefinition.getDefaultValue(), inputValueDefinition.getType())); + parameter.setType(getInputType(mappingContext, namedDefinition)); + parameter.setDefaultValue(getDefaultValue(mappingContext, namedDefinition, inputValueDefinition)); parameter.setVisibility(Utils.getFieldVisibility(mappingContext)); parameter.setAnnotations(annotationsMapper.getAnnotations(mappingContext, inputValueDefinition.getType(), inputValueDefinition, parentTypeName, false)); @@ -77,4 +77,26 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit return parameter; } + private String getDefaultValue(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition) { + String value = valueMapper.map(mappingContext, inputValueDefinition.getDefaultValue(), inputValueDefinition.getType()); + + if (!namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST)) { + if(value == null) { + return "java.util.Optional.empty()"; + } else { + return "java.util.Optional.of(" + value + ")"; + } + } else { + return value; + } + } + + private String getInputType(MappingContext mappingContext, NamedDefinition namedDefinition) { + String computedTypeName = namedDefinition.getJavaName(); + if (!namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + computedTypeName = graphQLTypeMapper.getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); + } + + return graphQLTypeMapper.getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); + } } From 7aff0144d1c54b9d2fe82f29a1236572a0343bca Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Fri, 12 Jan 2024 12:34:13 +0100 Subject: [PATCH 02/18] optional POC --- .../mapper/InputValueDefinitionToParameterMapper.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java index 5f181b083..ae1c2ab86 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java @@ -77,11 +77,15 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit return parameter; } + static final boolean ENABLE_OPTIONAL_INPUT = true; + private String getDefaultValue(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition) { String value = valueMapper.map(mappingContext, inputValueDefinition.getDefaultValue(), inputValueDefinition.getType()); - if (!namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST)) { - if(value == null) { + if (ENABLE_OPTIONAL_INPUT && + !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST) && + value != null) { + if (inputValueDefinition.getDefaultValue() instanceof NullValue) { return "java.util.Optional.empty()"; } else { return "java.util.Optional.of(" + value + ")"; @@ -93,7 +97,7 @@ private String getDefaultValue(MappingContext mappingContext, NamedDefinition na private String getInputType(MappingContext mappingContext, NamedDefinition namedDefinition) { String computedTypeName = namedDefinition.getJavaName(); - if (!namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + if (ENABLE_OPTIONAL_INPUT && !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { computedTypeName = graphQLTypeMapper.getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); } From 6f66d6a86dd73ba0c4cf536d88fb4cd7eae9e631 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Mon, 15 Jan 2024 12:10:54 +0100 Subject: [PATCH 03/18] optional POC --- .../InputValueDefinitionToParameterMapper.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java index ae1c2ab86..075c8ebb5 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java @@ -8,7 +8,6 @@ import graphql.language.*; import java.util.List; -import java.util.Optional; import static java.util.stream.Collectors.toList; @@ -64,11 +63,10 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit ParameterDefinition parameter = new ParameterDefinition(); parameter.setName(dataModelMapper.capitalizeIfRestricted(mappingContext, inputValueDefinition.getName())); parameter.setOriginalName(inputValueDefinition.getName()); - parameter.setType(getInputType(mappingContext, namedDefinition)); - parameter.setDefaultValue(getDefaultValue(mappingContext, namedDefinition, inputValueDefinition)); + parameter.setType(getInputType(mappingContext, namedDefinition, parentTypeName)); + parameter.setDefaultValue(getDefaultValue(mappingContext, namedDefinition, inputValueDefinition, parentTypeName)); parameter.setVisibility(Utils.getFieldVisibility(mappingContext)); - parameter.setAnnotations(annotationsMapper.getAnnotations(mappingContext, inputValueDefinition.getType(), - inputValueDefinition, parentTypeName, false)); + parameter.setAnnotations(annotationsMapper.getAnnotations(mappingContext, inputValueDefinition.getType(), inputValueDefinition, parentTypeName, false)); parameter.setDeprecated(DeprecatedDefinitionBuilder.build(mappingContext, inputValueDefinition)); parameter.setMandatory(namedDefinition.isMandatory()); parameter.setSerializeUsingObjectMapper(namedDefinition.isSerializeUsingObjectMapper()); @@ -79,10 +77,11 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit static final boolean ENABLE_OPTIONAL_INPUT = true; - private String getDefaultValue(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition) { + private String getDefaultValue(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String parentTypeName) { String value = valueMapper.map(mappingContext, inputValueDefinition.getDefaultValue(), inputValueDefinition.getType()); if (ENABLE_OPTIONAL_INPUT && + mappingContext.getInputsName().contains(parentTypeName) && !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST) && value != null) { if (inputValueDefinition.getDefaultValue() instanceof NullValue) { @@ -95,9 +94,11 @@ private String getDefaultValue(MappingContext mappingContext, NamedDefinition na } } - private String getInputType(MappingContext mappingContext, NamedDefinition namedDefinition) { + private String getInputType(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { String computedTypeName = namedDefinition.getJavaName(); - if (ENABLE_OPTIONAL_INPUT && !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + if (ENABLE_OPTIONAL_INPUT && + mappingContext.getInputsName().contains(parentTypeName) && + !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { computedTypeName = graphQLTypeMapper.getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); } From dba9bab0e3f99fa6ec37c16e04943ba864688681 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Mon, 15 Jan 2024 12:52:20 +0100 Subject: [PATCH 04/18] optional POC --- .../codegen/java/JavaGraphQLTypeMapper.java | 30 +++++++++++++++++ .../kotlin/KotlinGraphQLTypeMapper.java | 13 ++++++++ .../codegen/mapper/GraphQLTypeMapper.java | 13 +++----- ...InputValueDefinitionToParameterMapper.java | 32 +++---------------- .../model/GraphQLCodegenConfiguration.java | 7 ++++ .../graphql/codegen/model/MappingConfig.java | 12 +++++++ .../codegen/model/MappingConfigConstants.java | 2 ++ ...MappingConfigDefaultValuesInitializer.java | 4 +++ .../graphql/codegen/model/MappingContext.java | 5 +++ .../codegen/scala/ScalaGraphQLTypeMapper.java | 20 ++++++++++++ 10 files changed, 101 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java index 223aa953a..585a49991 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java @@ -7,6 +7,8 @@ import com.kobylynskyi.graphql.codegen.model.NamedDefinition; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; import com.kobylynskyi.graphql.codegen.utils.Utils; +import graphql.language.InputValueDefinition; +import graphql.language.NullValue; import java.util.HashSet; import java.util.Map; @@ -126,4 +128,32 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, String gra mandatory, primitiveCanBeUsed, serializeUsingObjectMapper); } + @Override + public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { + String computedTypeName = namedDefinition.getJavaName(); + if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableInputTypes()) && + mappingContext.getInputsName().contains(parentTypeName) && + !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + return getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); + } + + return getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); + } + + @Override + public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { + if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableInputTypes()) && + mappingContext.getInputsName().contains(parentTypeName) && + !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST) && + defaultValue != null) { + if (inputValueDefinition.getDefaultValue() instanceof NullValue) { + return JAVA_UTIL_OPTIONAL + ".empty()"; + } else { + return JAVA_UTIL_OPTIONAL + ".of(" + defaultValue + ")"; + } + } else { + return defaultValue; + } + } + } \ No newline at end of file diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java index e98b4745c..69b8f8d25 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java @@ -8,6 +8,7 @@ import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedFieldDefinition; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; import com.kobylynskyi.graphql.codegen.utils.Utils; +import graphql.language.InputValueDefinition; import java.util.HashSet; import java.util.Set; @@ -187,4 +188,16 @@ public String getResponseReturnType(MappingContext mappingContext, ExtendedField // Should fix it when generate response class. return getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); } + + static final boolean ENABLE_OPTIONAL_INPUT = true; + + @Override + public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { + return getTypeConsideringPrimitive(mappingContext, namedDefinition, namedDefinition.getJavaName()); + } + + @Override + public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { + return defaultValue; + } } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java index 0b1e372e6..7a9341d1c 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java @@ -4,15 +4,7 @@ import com.kobylynskyi.graphql.codegen.model.NamedDefinition; import com.kobylynskyi.graphql.codegen.model.RelayConfig; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedFieldDefinition; -import graphql.language.Argument; -import graphql.language.Directive; -import graphql.language.DirectivesContainer; -import graphql.language.ListType; -import graphql.language.NamedNode; -import graphql.language.NonNullType; -import graphql.language.StringValue; -import graphql.language.Type; -import graphql.language.TypeName; +import graphql.language.*; import java.util.Collections; import java.util.List; @@ -274,4 +266,7 @@ protected boolean isInterfaceOrUnion(MappingContext mappingContext, String graph mappingContext.getUnionsNames().contains(graphQLType); } + public abstract String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName); + + public abstract String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName); } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java index 075c8ebb5..5396380af 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java @@ -63,8 +63,8 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit ParameterDefinition parameter = new ParameterDefinition(); parameter.setName(dataModelMapper.capitalizeIfRestricted(mappingContext, inputValueDefinition.getName())); parameter.setOriginalName(inputValueDefinition.getName()); - parameter.setType(getInputType(mappingContext, namedDefinition, parentTypeName)); - parameter.setDefaultValue(getDefaultValue(mappingContext, namedDefinition, inputValueDefinition, parentTypeName)); + parameter.setType(graphQLTypeMapper.wrapApiInputTypeIfRequired(mappingContext, namedDefinition, parentTypeName)); + parameter.setDefaultValue(getDefaultValue(mappingContext, inputValueDefinition, parentTypeName, namedDefinition)); parameter.setVisibility(Utils.getFieldVisibility(mappingContext)); parameter.setAnnotations(annotationsMapper.getAnnotations(mappingContext, inputValueDefinition.getType(), inputValueDefinition, parentTypeName, false)); parameter.setDeprecated(DeprecatedDefinitionBuilder.build(mappingContext, inputValueDefinition)); @@ -75,33 +75,9 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit return parameter; } - static final boolean ENABLE_OPTIONAL_INPUT = true; - - private String getDefaultValue(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String parentTypeName) { + private String getDefaultValue(MappingContext mappingContext, InputValueDefinition inputValueDefinition, String parentTypeName, NamedDefinition namedDefinition) { String value = valueMapper.map(mappingContext, inputValueDefinition.getDefaultValue(), inputValueDefinition.getType()); - - if (ENABLE_OPTIONAL_INPUT && - mappingContext.getInputsName().contains(parentTypeName) && - !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST) && - value != null) { - if (inputValueDefinition.getDefaultValue() instanceof NullValue) { - return "java.util.Optional.empty()"; - } else { - return "java.util.Optional.of(" + value + ")"; - } - } else { - return value; - } + return graphQLTypeMapper.wrapApiDefaultValueIfRequired(mappingContext, namedDefinition, inputValueDefinition, value, parentTypeName); } - private String getInputType(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { - String computedTypeName = namedDefinition.getJavaName(); - if (ENABLE_OPTIONAL_INPUT && - mappingContext.getInputsName().contains(parentTypeName) && - !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { - computedTypeName = graphQLTypeMapper.getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); - } - - return graphQLTypeMapper.getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); - } } 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 dfb7db970..72c0f5ef2 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java @@ -356,6 +356,13 @@ public interface GraphQLCodegenConfiguration { */ Boolean getUseOptionalForNullableReturnTypes(); + /** + * Specifies whether input types of generated API interface should be wrapped into java.util.Optional + * + * @return true if input types should be wrapped into java.util.Optional + */ + Boolean getUseOptionalForNullableInputTypes(); + /** * 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). 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 dc29f4607..e77b9ed29 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java @@ -52,6 +52,7 @@ public class MappingConfig implements GraphQLCodegenConfiguration, Combinable getFieldsWithResolvers() { return fieldsWithResolvers; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java index 55e984e51..9818010f0 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java @@ -52,6 +52,8 @@ public class MappingConfigConstants { public static final boolean DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES = false; public static final String DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES_STRING = "false"; + public static final boolean DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES = false; + public static final String DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES_STRING = "false"; public static final ApiNamePrefixStrategy DEFAULT_API_NAME_PREFIX_STRATEGY = ApiNamePrefixStrategy.CONSTANT; public static final String DEFAULT_API_NAME_PREFIX_STRATEGY_STRING = "CONSTANT"; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java index 76e5a8e51..9bf83433e 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java @@ -87,6 +87,10 @@ public static void initDefaultValues(MappingConfig mappingConfig) { mappingConfig.setUseOptionalForNullableReturnTypes( MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES); } + if (mappingConfig.getUseOptionalForNullableInputTypes() == null) { + mappingConfig.setUseOptionalForNullableInputTypes( + MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES); + } if (mappingConfig.getApiNamePrefixStrategy() == null) { mappingConfig.setApiNamePrefixStrategy(MappingConfigConstants.DEFAULT_API_NAME_PREFIX_STRATEGY); } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java index f3531ca02..6059b7899 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java @@ -259,6 +259,11 @@ public Boolean getUseOptionalForNullableReturnTypes() { return config.getUseOptionalForNullableReturnTypes(); } + @Override + public Boolean getUseOptionalForNullableInputTypes() { + return config.getUseOptionalForNullableInputTypes(); + } + @Override public Set getFieldsWithResolvers() { return config.getFieldsWithResolvers(); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java index 15b68d616..948cae2da 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java @@ -6,6 +6,8 @@ import com.kobylynskyi.graphql.codegen.model.NamedDefinition; import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; import com.kobylynskyi.graphql.codegen.utils.Utils; +import graphql.language.InputValueDefinition; +import graphql.language.NullValue; import java.util.HashSet; import java.util.Set; @@ -116,4 +118,22 @@ public String getGenericsString(MappingContext mappingContext, String genericTyp } } + @Override + public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { + String computedTypeName = namedDefinition.getJavaName(); + if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableInputTypes()) && + mappingContext.getInputsName().contains(parentTypeName) && + !namedDefinition.isMandatory() && !computedTypeName.startsWith(SCALA_UTIL_LIST) && + !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + return getGenericsString(mappingContext, SCALA_UTIL_OPTIONAL, computedTypeName); + } + + return getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); + } + + @Override + public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { + return defaultValue; + } + } From d4763127338f06659e7ef1c6d6275485090cfaed Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Mon, 15 Jan 2024 13:00:27 +0100 Subject: [PATCH 05/18] new config --- .../kobylynskyi/graphql/codegen/GraphQLCodegenMojo.java | 9 +++++++++ 1 file changed, 9 insertions(+) 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 a71c11a4e..50664d266 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 @@ -153,6 +153,9 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo @Parameter(defaultValue = MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES_STRING) private boolean useOptionalForNullableReturnTypes; + @Parameter(defaultValue = MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES_STRING) + private boolean useOptionalForNullableInputTypes; + @Parameter(defaultValue = MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_THROWS_EXCEPTION_STRING) private boolean generateApisWithThrowsException; @@ -291,6 +294,7 @@ public void execute() throws MojoExecutionException { mappingConfig.setGenerateExtensionFieldsResolvers(generateExtensionFieldsResolvers); mappingConfig.setGenerateModelsForRootTypes(generateModelsForRootTypes); mappingConfig.setUseOptionalForNullableReturnTypes(useOptionalForNullableReturnTypes); + mappingConfig.setUseOptionalForNullableInputTypes(useOptionalForNullableInputTypes); mappingConfig.setGenerateApisWithThrowsException(generateApisWithThrowsException); mappingConfig.setGenerateApisWithSuspendFunctions(generateApisWithSuspendFunctions); mappingConfig.setGenerateJacksonTypeIdResolver(generateJacksonTypeIdResolver); @@ -563,6 +567,11 @@ public Boolean getUseOptionalForNullableReturnTypes() { return useOptionalForNullableReturnTypes; } + @Override + public Boolean getUseOptionalForNullableInputTypes() { + return useOptionalForNullableInputTypes; + } + @Override public Boolean getGenerateApisWithThrowsException() { return generateApisWithThrowsException; From 9d2b5b9da08976ef381f89d9565f9edb069bda2e Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Tue, 16 Jan 2024 12:36:01 +0100 Subject: [PATCH 06/18] graphql input param wrapper --- .../graphql/codegen/GraphQLCodegenMojo.java | 20 ++-- .../generators/FilesGeneratorsFactory.java | 13 +- .../generators/FreeMarkerTemplateType.java | 3 +- .../impl/InputWrapperGenerator.java | 47 ++++++++ .../codegen/java/JavaGraphQLTypeMapper.java | 30 ++--- .../codegen/mapper/DataModelMapper.java | 4 +- .../model/GraphQLCodegenConfiguration.java | 4 +- .../graphql/codegen/model/MappingConfig.java | 20 ++-- ...MappingConfigDefaultValuesInitializer.java | 4 +- .../graphql/codegen/model/MappingContext.java | 21 +--- .../codegen/scala/ScalaGraphQLTypeMapper.java | 23 ++-- .../java-lang/graphql_input_parameter.ftl | 111 ++++++++++++++++++ .../kotlin-lang/graphql_input_parameter.ftl | 0 .../scala-lang/graphql_input_parameter.ftl | 0 14 files changed, 215 insertions(+), 85 deletions(-) create mode 100644 src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java create mode 100644 src/main/resources/templates/java-lang/graphql_input_parameter.ftl create mode 100644 src/main/resources/templates/kotlin-lang/graphql_input_parameter.ftl create mode 100644 src/main/resources/templates/scala-lang/graphql_input_parameter.ftl 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 50664d266..281487339 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 @@ -154,7 +154,7 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo private boolean useOptionalForNullableReturnTypes; @Parameter(defaultValue = MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES_STRING) - private boolean useOptionalForNullableInputTypes; + private boolean useWrapperForNullableInputTypes; @Parameter(defaultValue = MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_THROWS_EXCEPTION_STRING) private boolean generateApisWithThrowsException; @@ -294,7 +294,7 @@ public void execute() throws MojoExecutionException { mappingConfig.setGenerateExtensionFieldsResolvers(generateExtensionFieldsResolvers); mappingConfig.setGenerateModelsForRootTypes(generateModelsForRootTypes); mappingConfig.setUseOptionalForNullableReturnTypes(useOptionalForNullableReturnTypes); - mappingConfig.setUseOptionalForNullableInputTypes(useOptionalForNullableInputTypes); + mappingConfig.setUseWrapperForNullableInputTypes(useWrapperForNullableInputTypes); mappingConfig.setGenerateApisWithThrowsException(generateApisWithThrowsException); mappingConfig.setGenerateApisWithSuspendFunctions(generateApisWithSuspendFunctions); mappingConfig.setGenerateJacksonTypeIdResolver(generateJacksonTypeIdResolver); @@ -353,10 +353,10 @@ private GraphQLCodegen instantiateCodegen(MappingConfig mappingConfig) throws IO if (skipSchemaSizeLimit) { ParserOptions.Builder parserOptionBuilder = ParserOptions.newParserOptions() - .maxTokens(Integer.MAX_VALUE) - .maxCharacters(Integer.MAX_VALUE) - .maxWhitespaceTokens(Integer.MAX_VALUE) - .maxRuleDepth(Integer.MAX_VALUE); + .maxTokens(Integer.MAX_VALUE) + .maxCharacters(Integer.MAX_VALUE) + .maxWhitespaceTokens(Integer.MAX_VALUE) + .maxRuleDepth(Integer.MAX_VALUE); ParserOptions.setDefaultParserOptions(parserOptionBuilder.build()); } @@ -568,8 +568,8 @@ public Boolean getUseOptionalForNullableReturnTypes() { } @Override - public Boolean getUseOptionalForNullableInputTypes() { - return useOptionalForNullableInputTypes; + public Boolean getUseWrapperForNullableInputTypes() { + return useWrapperForNullableInputTypes; } @Override @@ -784,8 +784,8 @@ private static Map convertToMap(Properties properties) { result.put(name, properties.getProperty(name)); } return result; - } - + } + @Override public File getCustomTemplatesRoot() { return customTemplatesRoot == null ? project.getBasedir() : customTemplatesRoot; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java index a444d4536..ad1efe622 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java @@ -1,16 +1,6 @@ package com.kobylynskyi.graphql.codegen.generators; -import com.kobylynskyi.graphql.codegen.generators.impl.EnumsGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.FieldResolversGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.InputGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.InterfaceGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.JacksonTypeIdResolverGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.OperationsGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.ParametrizedInputGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.RequestResponseGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.ResponseProjectionGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.TypeGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.UnionGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.*; import com.kobylynskyi.graphql.codegen.mapper.DataModelMapperFactory; import com.kobylynskyi.graphql.codegen.model.MappingContext; @@ -41,6 +31,7 @@ public static List getAll(MappingContext context, generators.add(new ResponseProjectionGenerator(context, dataModelMapperFactory)); generators.add(new ParametrizedInputGenerator(context, dataModelMapperFactory)); generators.add(new FieldResolversGenerator(context, dataModelMapperFactory)); + generators.add(new InputWrapperGenerator(context)); generators.add(new InputGenerator(context, dataModelMapperFactory)); generators.add(new UnionGenerator(context, dataModelMapperFactory)); generators.add(new RequestResponseGenerator(context, dataModelMapperFactory)); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java index 87229e4f4..a0a788a17 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java @@ -14,6 +14,7 @@ public enum FreeMarkerTemplateType { OPERATIONS, PARAMETRIZED_INPUT, RESPONSE_PROJECTION, - JACKSON_TYPE_ID_RESOLVER + JACKSON_TYPE_ID_RESOLVER, + GRAPHQL_INPUT_PARAMETER } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java new file mode 100644 index 000000000..9f57766ba --- /dev/null +++ b/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java @@ -0,0 +1,47 @@ +package com.kobylynskyi.graphql.codegen.generators.impl; + +import com.kobylynskyi.graphql.codegen.generators.FilesGenerator; +import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateFilesCreator; +import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType; +import com.kobylynskyi.graphql.codegen.mapper.DataModelMapper; +import com.kobylynskyi.graphql.codegen.model.MappingContext; + +import java.io.File; +import java.util.*; + +import static com.kobylynskyi.graphql.codegen.model.DataModelFields.*; + +/** + * Generates files for inputs + */ +public class InputWrapperGenerator implements FilesGenerator { + + public static final String CLASS_NAME_GRAPHQL_INPUT_PARAMETER = "GraphQLInputParameter"; + private final MappingContext mappingContext; + + public InputWrapperGenerator(MappingContext mappingContext) { + this.mappingContext = mappingContext; + } + + @Override + public List generate() { + List generatedFiles = new ArrayList<>(); + if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes())) { + String packageName = DataModelMapper.getModelPackageName(mappingContext); + Set imports = DataModelMapper.getImports(mappingContext, packageName); + + Map dataModel = new HashMap<>(); + dataModel.put(NAME, CLASS_NAME_GRAPHQL_INPUT_PARAMETER); + dataModel.put(CLASS_NAME, CLASS_NAME_GRAPHQL_INPUT_PARAMETER); + dataModel.put(PACKAGE, packageName); + dataModel.put(IMPORTS, imports); + dataModel.put(GENERATED_ANNOTATION, mappingContext.getAddGeneratedAnnotation()); + dataModel.put(GENERATED_INFO, mappingContext.getGeneratedInformation()); + generatedFiles.add(FreeMarkerTemplateFilesCreator + .create(mappingContext, FreeMarkerTemplateType.GRAPHQL_INPUT_PARAMETER, dataModel)); + } + + return generatedFiles; + } + +} diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java index 585a49991..8f1ff1559 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java @@ -26,6 +26,7 @@ public class JavaGraphQLTypeMapper extends GraphQLTypeMapper { public static final String JAVA_UTIL_LIST = "java.util.List"; public static final Pattern JAVA_UTIL_LIST_ELEMENT_REGEX = Pattern.compile("java\\.util\\.List<(.+)>"); private static final String JAVA_UTIL_OPTIONAL = "java.util.Optional"; + private static final String INPUT_WRAPPER_CLASS = "GraphQLInputParameter"; private static final Set JAVA_PRIMITIVE_TYPES = new HashSet<>(asList( "byte", "short", "int", "long", "float", "double", "char", "boolean")); @@ -58,18 +59,18 @@ public String wrapApiReturnTypeIfRequired(MappingContext mappingContext, String parentTypeName) { String computedTypeName = namedDefinition.getJavaName(); if (parentTypeName.equalsIgnoreCase(GraphQLOperation.SUBSCRIPTION.name()) && - Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { + Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { // in case it is subscription and subscriptionReturnType is set return getGenericsString(mappingContext, mappingContext.getSubscriptionReturnType(), computedTypeName); } if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableReturnTypes()) - && !namedDefinition.isMandatory() - && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + && !namedDefinition.isMandatory() + && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { computedTypeName = getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); } if (computedTypeName.startsWith(JAVA_UTIL_LIST) && - Utils.isNotBlank(mappingContext.getApiReturnListType())) { + Utils.isNotBlank(mappingContext.getApiReturnListType())) { // in case it is query/mutation, return type is list and apiReturnListType is set if (mappingContext.getApiReturnListType().contains(MappingConfigConstants.API_RETURN_NAME_PLACEHOLDER)) { Matcher matcher = JAVA_UTIL_LIST_ELEMENT_REGEX.matcher(computedTypeName); @@ -119,8 +120,8 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, String gra langTypeName = DataModelMapper.getModelClassNameWithPrefixAndSuffix(mappingContext, graphQLType); } if (serializeFieldsUsingObjectMapper.contains(graphQLType) || - (name != null && parentTypeName != null && - serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name))) { + (name != null && parentTypeName != null && + serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name))) { serializeUsingObjectMapper = true; } @@ -131,10 +132,10 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, String gra @Override public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { String computedTypeName = namedDefinition.getJavaName(); - if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableInputTypes()) && + if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes()) && mappingContext.getInputsName().contains(parentTypeName) && !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { - return getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); + return getGenericsString(mappingContext, INPUT_WRAPPER_CLASS, computedTypeName); } return getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); @@ -142,14 +143,15 @@ public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDef @Override public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { - if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableInputTypes()) && + if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes()) && mappingContext.getInputsName().contains(parentTypeName) && - !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST) && - defaultValue != null) { - if (inputValueDefinition.getDefaultValue() instanceof NullValue) { - return JAVA_UTIL_OPTIONAL + ".empty()"; + !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST)) { + if (defaultValue == null) { + return INPUT_WRAPPER_CLASS + ".undefined()"; + } else if (inputValueDefinition.getDefaultValue() instanceof NullValue) { + return INPUT_WRAPPER_CLASS + ".withNull()"; } else { - return JAVA_UTIL_OPTIONAL + ".of(" + defaultValue + ")"; + return INPUT_WRAPPER_CLASS + ".withValue(" + defaultValue + ")"; } } else { return defaultValue; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java index 0eab1476e..33ae20d51 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java @@ -205,7 +205,7 @@ static String getParametrizedInputClassName(MappingContext mappingContext, * @param mappingContext Global mapping context * @return api package name if present. Generic package name otherwise */ - static String getApiPackageName(MappingContext mappingContext) { + public static String getApiPackageName(MappingContext mappingContext) { if (Utils.isNotBlank(mappingContext.getApiPackageName())) { return mappingContext.getApiPackageName(); } else { @@ -236,7 +236,7 @@ public static String getModelPackageName(MappingContext mappingContext) { * @param packageName Package name of the generated class which will be ignored * @return all imports required for a generated class */ - static Set getImports(MappingContext mappingContext, String packageName) { + public static Set getImports(MappingContext mappingContext, String packageName) { Set imports = new HashSet<>(); String modelPackageName = mappingContext.getModelPackageName(); if (Utils.isNotBlank(modelPackageName) && !modelPackageName.equals(packageName)) { 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 72c0f5ef2..a56ae33e4 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java @@ -28,7 +28,7 @@ public interface GraphQLCodegenConfiguration { * @return mappings from GraphqlType to JavaType */ Map getCustomTypesMapping(); - + /** * Can be used to specify the root directory for the custom FreeMaker templates * @@ -361,7 +361,7 @@ public interface GraphQLCodegenConfiguration { * * @return true if input types should be wrapped into java.util.Optional */ - Boolean getUseOptionalForNullableInputTypes(); + Boolean getUseWrapperForNullableInputTypes(); /** * Specifies whether client-side classes should be generated for each query, mutation and subscription. 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 e77b9ed29..6d1db45a6 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java @@ -1,11 +1,7 @@ package com.kobylynskyi.graphql.codegen.model; import java.io.File; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Function; /** @@ -52,7 +48,7 @@ public class MappingConfig implements GraphQLCodegenConfiguration, Combinable> getParentInterfaceProperties() { // In this way, we no longer need to rely on the order in which files are created // Only for scala/kotlin if ((GeneratedLanguage.SCALA.equals(this.config.getGeneratedLanguage()) || - GeneratedLanguage.KOTLIN.equals(this.config.getGeneratedLanguage())) && - parentInterfaceProperties == null) { + GeneratedLanguage.KOTLIN.equals(this.config.getGeneratedLanguage())) && + parentInterfaceProperties == null) { parentInterfaceProperties = new HashMap<>(); for (ExtendedInterfaceTypeDefinition interfaceDef : this.document.getInterfaceDefinitions()) { String clazzName = getModelClassNameWithPrefixAndSuffix(interfaceDef); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java index 948cae2da..e97772334 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java @@ -7,7 +7,6 @@ import com.kobylynskyi.graphql.codegen.model.graphql.GraphQLOperation; import com.kobylynskyi.graphql.codegen.utils.Utils; import graphql.language.InputValueDefinition; -import graphql.language.NullValue; import java.util.HashSet; import java.util.Set; @@ -60,23 +59,23 @@ public String wrapApiReturnTypeIfRequired(MappingContext mappingContext, String parentTypeName) { String computedTypeName = namedDefinition.getJavaName(); if (parentTypeName.equalsIgnoreCase(GraphQLOperation.SUBSCRIPTION.name()) && - Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { + Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { // in case it is subscription and subscriptionReturnType is set return getGenericsString(mappingContext, mappingContext.getSubscriptionReturnType(), computedTypeName); } if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableReturnTypes()) - && !namedDefinition.isMandatory() - && !computedTypeName.startsWith(SCALA_UTIL_LIST) - && !computedTypeName.startsWith(JAVA_UTIL_LIST) - && !computedTypeName.startsWith(SCALA_UTIL_OPTIONAL)) { + && !namedDefinition.isMandatory() + && !computedTypeName.startsWith(SCALA_UTIL_LIST) + && !computedTypeName.startsWith(JAVA_UTIL_LIST) + && !computedTypeName.startsWith(SCALA_UTIL_OPTIONAL)) { // Kotlin/Scala: primitive types is Option by default // wrap the type into scala.Option (except java list and scala list) computedTypeName = getGenericsString(mappingContext, SCALA_UTIL_OPTIONAL, computedTypeName); } if (computedTypeName.startsWith(SCALA_UTIL_LIST) && - Utils.isNotBlank(mappingContext.getApiReturnListType())) { + Utils.isNotBlank(mappingContext.getApiReturnListType())) { // in case it is query/mutation, return type is list and apiReturnListType is set if (mappingContext.getApiReturnListType().contains(MappingConfigConstants.API_RETURN_NAME_PLACEHOLDER)) { Matcher matcher = SCALA_UTIL_LIST_ELEMENT_REGEX.matcher(computedTypeName); @@ -120,15 +119,7 @@ public String getGenericsString(MappingContext mappingContext, String genericTyp @Override public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { - String computedTypeName = namedDefinition.getJavaName(); - if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableInputTypes()) && - mappingContext.getInputsName().contains(parentTypeName) && - !namedDefinition.isMandatory() && !computedTypeName.startsWith(SCALA_UTIL_LIST) && - !computedTypeName.startsWith(JAVA_UTIL_LIST)) { - return getGenericsString(mappingContext, SCALA_UTIL_OPTIONAL, computedTypeName); - } - - return getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); + return getTypeConsideringPrimitive(mappingContext, namedDefinition, namedDefinition.getJavaName()); } @Override diff --git a/src/main/resources/templates/java-lang/graphql_input_parameter.ftl b/src/main/resources/templates/java-lang/graphql_input_parameter.ftl new file mode 100644 index 000000000..d73f6b1e6 --- /dev/null +++ b/src/main/resources/templates/java-lang/graphql_input_parameter.ftl @@ -0,0 +1,111 @@ +<#if package?has_content> +package ${package}; + +<#list imports as import> +import ${import}.*; + + + +<#if generatedAnnotation && generatedInfo.getGeneratedType()?has_content> +@${generatedInfo.getGeneratedType()}( +value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", +date = "${generatedInfo.getDateTime()}" +) + +/** + * A wrapper class for GraphQL input parameters that supports values, null, or undefined. + * This class is designed to handle various types using generics. + * + * @param The type of the input parameter. + */ +public class GraphQLInputParameter { + + private T value; + private boolean isDefined; + + /** + * Private constructor to create a GraphQLInputParameter instance with a value and definition status. + * + * @param value The value of the input parameter. + * @param isDefined A boolean flag indicating whether the value is defined. + */ + private GraphQLInputParameter(T value, boolean isDefined) { + this.value = value; + this.isDefined = isDefined; + } + + /** + * Creates a GraphQLInputParameter instance with a specified value. + * + * @param The type of the input parameter. + * @param value The value of the input parameter. + * @return A GraphQLInputParameter instance with the specified value. + */ + public static GraphQLInputParameter withValue(T value) { + return new GraphQLInputParameter<>(value, true); + } + + /** + * Creates a GraphQLInputParameter instance with a null value. + * + * @param The type of the input parameter. + * @return A GraphQLInputParameter instance with a null value. + */ + public static GraphQLInputParameter withNull() { + return new GraphQLInputParameter<>(null, true); + } + + /** + * Creates a GraphQLInputParameter instance representing an undefined value. + * + * @param The type of the input parameter. + * @return A GraphQLInputParameter instance representing an undefined value. + */ + public static GraphQLInputParameter undefined() { + return new GraphQLInputParameter<>(null, false); + } + + /** + * Checks whether the input parameter has a defined value. + * + * @return {@code true} if the value is defined, {@code false} otherwise. + */ + public boolean isDefined() { + return isDefined; + } + + /** + * Checks whether the input parameter does not have a defined value. + * + * @return {@code false} if the value is defined, {@code true} otherwise. + */ + public boolean isUndefined() { + return !isDefined; + } + + /** + * Gets the value of the input parameter. Throws an IllegalStateException if the value is undefined. + * + * @return The value of the input parameter. + * @throws IllegalStateException If the value is undefined. + */ + public T getValue() { + if (!isDefined) { + throw new IllegalStateException("Value is undefined"); + } + return value; + } + + /** + * Gets the value of the input parameter or default value. + * @param The type of the input parameter. + * @param defaultValue The value to return if the input parameter is undefined. + * @return The value of the input parameter, or a default value if undefined. + */ + public T getValueOrDefault(T defaultValue) { + if (!isDefined) { + return defaultValue; + } + return value; + } +} \ No newline at end of file diff --git a/src/main/resources/templates/kotlin-lang/graphql_input_parameter.ftl b/src/main/resources/templates/kotlin-lang/graphql_input_parameter.ftl new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/resources/templates/scala-lang/graphql_input_parameter.ftl b/src/main/resources/templates/scala-lang/graphql_input_parameter.ftl new file mode 100644 index 000000000..e69de29bb From 15ffda607c861844f7c67c22091b0a6777744b1a Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Tue, 16 Jan 2024 12:58:56 +0100 Subject: [PATCH 07/18] add tests --- .../GraphQLCodegenInputWrapperTest.java | 59 +++++ .../GraphQLInputParameter.java.txt | 103 +++++++++ .../input-wrapper/InputWithDefaults.java.txt | 209 ++++++++++++++++++ .../input-wrapper/MyEnum.java.txt | 22 ++ .../input-wrapper/SomeObject.java.txt | 70 ++++++ .../resources/schemas/input-wrapper.graphqls | 23 ++ 6 files changed, 486 insertions(+) create mode 100644 src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java create mode 100644 src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt create mode 100644 src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt create mode 100644 src/test/resources/expected-classes/input-wrapper/MyEnum.java.txt create mode 100644 src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt create mode 100644 src/test/resources/schemas/input-wrapper.graphqls diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java new file mode 100644 index 000000000..57fd6f4e8 --- /dev/null +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java @@ -0,0 +1,59 @@ +package com.kobylynskyi.graphql.codegen; + +import com.kobylynskyi.graphql.codegen.java.JavaGraphQLCodegen; +import com.kobylynskyi.graphql.codegen.model.MappingConfig; +import com.kobylynskyi.graphql.codegen.utils.Utils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +import static com.kobylynskyi.graphql.codegen.TestUtils.assertSameTrimmedContent; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static java.util.stream.Collectors.toList; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(MaxQueryTokensExtension.class) +class GraphQLCodegenInputWrapperTest { + + private final File outputBuildDir = new File("build/generated"); + private final File outputJavaClassesDir = new File("build/generated"); + private final MappingConfig mappingConfig = new MappingConfig(); + + @BeforeEach + void before() { + mappingConfig.setUseWrapperForNullableInputTypes(true); + } + + @AfterEach + void cleanup() { + Utils.deleteDir(outputBuildDir); + } + + @Test + void generate_CheckFiles() throws Exception { + generate("src/test/resources/schemas/input-wrapper.graphqls"); + + File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles()); + List generatedFileNames = Arrays.stream(files).map(File::getName).sorted().collect(toList()); + assertEquals(asList("GraphQLInputParameter.java", "InputWithDefaults.java", "MyEnum.java", "SomeObject.java"), generatedFileNames); + + for (File file : files) { + assertSameTrimmedContent(new File(String.format("src/test/resources/expected-classes/input-wrapper/%s.txt", + file.getName())), file); + } + } + + private void generate(String path) throws IOException { + new JavaGraphQLCodegen(singletonList(path), + outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo(mappingConfig)).generate(); + } + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt b/src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt new file mode 100644 index 000000000..1446f7972 --- /dev/null +++ b/src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt @@ -0,0 +1,103 @@ + + +@javax.annotation.Generated( +value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", +date = "2020-12-31T23:59:59-0500" +) +/** + * A wrapper class for GraphQL input parameters that supports values, null, or undefined. + * This class is designed to handle various types using generics. + * + * @param The type of the input parameter. + */ +public class GraphQLInputParameter { + + private T value; + private boolean isDefined; + + /** + * Private constructor to create a GraphQLInputParameter instance with a value and definition status. + * + * @param value The value of the input parameter. + * @param isDefined A boolean flag indicating whether the value is defined. + */ + private GraphQLInputParameter(T value, boolean isDefined) { + this.value = value; + this.isDefined = isDefined; + } + + /** + * Creates a GraphQLInputParameter instance with a specified value. + * + * @param The type of the input parameter. + * @param value The value of the input parameter. + * @return A GraphQLInputParameter instance with the specified value. + */ + public static GraphQLInputParameter withValue(T value) { + return new GraphQLInputParameter<>(value, true); + } + + /** + * Creates a GraphQLInputParameter instance with a null value. + * + * @param The type of the input parameter. + * @return A GraphQLInputParameter instance with a null value. + */ + public static GraphQLInputParameter withNull() { + return new GraphQLInputParameter<>(null, true); + } + + /** + * Creates a GraphQLInputParameter instance representing an undefined value. + * + * @param The type of the input parameter. + * @return A GraphQLInputParameter instance representing an undefined value. + */ + public static GraphQLInputParameter undefined() { + return new GraphQLInputParameter<>(null, false); + } + + /** + * Checks whether the input parameter has a defined value. + * + * @return {@code true} if the value is defined, {@code false} otherwise. + */ + public boolean isDefined() { + return isDefined; + } + + /** + * Checks whether the input parameter does not have a defined value. + * + * @return {@code false} if the value is defined, {@code true} otherwise. + */ + public boolean isUndefined() { + return !isDefined; + } + + /** + * Gets the value of the input parameter. Throws an IllegalStateException if the value is undefined. + * + * @return The value of the input parameter. + * @throws IllegalStateException If the value is undefined. + */ + public T getValue() { + if (!isDefined) { + throw new IllegalStateException("Value is undefined"); + } + return value; + } + + /** + * Gets the value of the input parameter or default value. + * @param The type of the input parameter. + * @param defaultValue The value to return if the input parameter is undefined. + * @return The value of the input parameter, or a default value if undefined. + */ + public T getValueOrDefault(T defaultValue) { + if (!isDefined) { + return defaultValue; + } + return value; + } +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt b/src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt new file mode 100644 index 000000000..8b88891e3 --- /dev/null +++ b/src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt @@ -0,0 +1,209 @@ + +/** + * This input has all possible types + */ +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class InputWithDefaults implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + private GraphQLInputParameter floatVal = GraphQLInputParameter.withValue(1.23); + private GraphQLInputParameter booleanVal = GraphQLInputParameter.withValue(false); + private GraphQLInputParameter intVal = GraphQLInputParameter.withValue(42); + private GraphQLInputParameter stringVal = GraphQLInputParameter.withValue("my-default"); + private GraphQLInputParameter enumVal = GraphQLInputParameter.withValue(MyEnum.ONE); + @javax.validation.constraints.NotNull + private MyEnum nonNullEnumVal = MyEnum.TWO; + private GraphQLInputParameter objectWithNullDefault = GraphQLInputParameter.withNull(); + private GraphQLInputParameter objectWithNonNullDefault = GraphQLInputParameter.undefined(); + private java.util.List intList = java.util.Arrays.asList(1, 2, 3); + private java.util.List intListEmptyDefault = java.util.Collections.emptyList(); + @javax.validation.constraints.NotNull + private java.util.List objectListEmptyDefault = java.util.Collections.emptyList(); + + public InputWithDefaults() { + } + + public InputWithDefaults(GraphQLInputParameter floatVal, GraphQLInputParameter booleanVal, GraphQLInputParameter intVal, GraphQLInputParameter stringVal, GraphQLInputParameter enumVal, MyEnum nonNullEnumVal, GraphQLInputParameter objectWithNullDefault, GraphQLInputParameter objectWithNonNullDefault, java.util.List intList, java.util.List intListEmptyDefault, java.util.List objectListEmptyDefault) { + this.floatVal = floatVal; + this.booleanVal = booleanVal; + this.intVal = intVal; + this.stringVal = stringVal; + this.enumVal = enumVal; + this.nonNullEnumVal = nonNullEnumVal; + this.objectWithNullDefault = objectWithNullDefault; + this.objectWithNonNullDefault = objectWithNonNullDefault; + this.intList = intList; + this.intListEmptyDefault = intListEmptyDefault; + this.objectListEmptyDefault = objectListEmptyDefault; + } + + public GraphQLInputParameter getFloatVal() { + return floatVal; + } + public void setFloatVal(GraphQLInputParameter floatVal) { + this.floatVal = floatVal; + } + + public GraphQLInputParameter getBooleanVal() { + return booleanVal; + } + public void setBooleanVal(GraphQLInputParameter booleanVal) { + this.booleanVal = booleanVal; + } + + public GraphQLInputParameter getIntVal() { + return intVal; + } + public void setIntVal(GraphQLInputParameter intVal) { + this.intVal = intVal; + } + + public GraphQLInputParameter getStringVal() { + return stringVal; + } + public void setStringVal(GraphQLInputParameter stringVal) { + this.stringVal = stringVal; + } + + public GraphQLInputParameter getEnumVal() { + return enumVal; + } + public void setEnumVal(GraphQLInputParameter enumVal) { + this.enumVal = enumVal; + } + + public MyEnum getNonNullEnumVal() { + return nonNullEnumVal; + } + public void setNonNullEnumVal(MyEnum nonNullEnumVal) { + this.nonNullEnumVal = nonNullEnumVal; + } + + public GraphQLInputParameter getObjectWithNullDefault() { + return objectWithNullDefault; + } + public void setObjectWithNullDefault(GraphQLInputParameter objectWithNullDefault) { + this.objectWithNullDefault = objectWithNullDefault; + } + + public GraphQLInputParameter getObjectWithNonNullDefault() { + return objectWithNonNullDefault; + } + public void setObjectWithNonNullDefault(GraphQLInputParameter objectWithNonNullDefault) { + this.objectWithNonNullDefault = objectWithNonNullDefault; + } + + public java.util.List getIntList() { + return intList; + } + public void setIntList(java.util.List intList) { + this.intList = intList; + } + + public java.util.List getIntListEmptyDefault() { + return intListEmptyDefault; + } + public void setIntListEmptyDefault(java.util.List intListEmptyDefault) { + this.intListEmptyDefault = intListEmptyDefault; + } + + public java.util.List getObjectListEmptyDefault() { + return objectListEmptyDefault; + } + public void setObjectListEmptyDefault(java.util.List objectListEmptyDefault) { + this.objectListEmptyDefault = objectListEmptyDefault; + } + + + + public static InputWithDefaults.Builder builder() { + return new InputWithDefaults.Builder(); + } + + @javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" + ) + public static class Builder { + + private GraphQLInputParameter floatVal = GraphQLInputParameter.withValue(1.23); + private GraphQLInputParameter booleanVal = GraphQLInputParameter.withValue(false); + private GraphQLInputParameter intVal = GraphQLInputParameter.withValue(42); + private GraphQLInputParameter stringVal = GraphQLInputParameter.withValue("my-default"); + private GraphQLInputParameter enumVal = GraphQLInputParameter.withValue(MyEnum.ONE); + private MyEnum nonNullEnumVal = MyEnum.TWO; + private GraphQLInputParameter objectWithNullDefault = GraphQLInputParameter.withNull(); + private GraphQLInputParameter objectWithNonNullDefault = GraphQLInputParameter.undefined(); + private java.util.List intList = java.util.Arrays.asList(1, 2, 3); + private java.util.List intListEmptyDefault = java.util.Collections.emptyList(); + private java.util.List objectListEmptyDefault = java.util.Collections.emptyList(); + + public Builder() { + } + + public Builder setFloatVal(GraphQLInputParameter floatVal) { + this.floatVal = floatVal; + return this; + } + + public Builder setBooleanVal(GraphQLInputParameter booleanVal) { + this.booleanVal = booleanVal; + return this; + } + + public Builder setIntVal(GraphQLInputParameter intVal) { + this.intVal = intVal; + return this; + } + + public Builder setStringVal(GraphQLInputParameter stringVal) { + this.stringVal = stringVal; + return this; + } + + public Builder setEnumVal(GraphQLInputParameter enumVal) { + this.enumVal = enumVal; + return this; + } + + public Builder setNonNullEnumVal(MyEnum nonNullEnumVal) { + this.nonNullEnumVal = nonNullEnumVal; + return this; + } + + public Builder setObjectWithNullDefault(GraphQLInputParameter objectWithNullDefault) { + this.objectWithNullDefault = objectWithNullDefault; + return this; + } + + public Builder setObjectWithNonNullDefault(GraphQLInputParameter objectWithNonNullDefault) { + this.objectWithNonNullDefault = objectWithNonNullDefault; + return this; + } + + public Builder setIntList(java.util.List intList) { + this.intList = intList; + return this; + } + + public Builder setIntListEmptyDefault(java.util.List intListEmptyDefault) { + this.intListEmptyDefault = intListEmptyDefault; + return this; + } + + public Builder setObjectListEmptyDefault(java.util.List objectListEmptyDefault) { + this.objectListEmptyDefault = objectListEmptyDefault; + return this; + } + + + public InputWithDefaults build() { + return new InputWithDefaults(floatVal, booleanVal, intVal, stringVal, enumVal, nonNullEnumVal, objectWithNullDefault, objectWithNonNullDefault, intList, intListEmptyDefault, objectListEmptyDefault); + } + + } +} diff --git a/src/test/resources/expected-classes/input-wrapper/MyEnum.java.txt b/src/test/resources/expected-classes/input-wrapper/MyEnum.java.txt new file mode 100644 index 000000000..299b7a492 --- /dev/null +++ b/src/test/resources/expected-classes/input-wrapper/MyEnum.java.txt @@ -0,0 +1,22 @@ +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public enum MyEnum { + + ONE("ONE"), + TWO("TWO"), + THREE("THREE"); + + private final String graphqlName; + + private MyEnum(String graphqlName) { + this.graphqlName = graphqlName; + } + + @Override + public String toString() { + return this.graphqlName; + } + +} \ No newline at end of file diff --git a/src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt b/src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt new file mode 100644 index 000000000..a96fbbff6 --- /dev/null +++ b/src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt @@ -0,0 +1,70 @@ + +@javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" +) +public class SomeObject implements java.io.Serializable { + + private static final long serialVersionUID = 1L; + + @javax.validation.constraints.NotNull + private String name; + private GraphQLInputParameter description = GraphQLInputParameter.undefined(); + + public SomeObject() { + } + + public SomeObject(String name, GraphQLInputParameter description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public GraphQLInputParameter getDescription() { + return description; + } + public void setDescription(GraphQLInputParameter description) { + this.description = description; + } + + + + public static SomeObject.Builder builder() { + return new SomeObject.Builder(); + } + + @javax.annotation.Generated( + value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", + date = "2020-12-31T23:59:59-0500" + ) + public static class Builder { + + private String name; + private GraphQLInputParameter description = GraphQLInputParameter.undefined(); + + public Builder() { + } + + public Builder setName(String name) { + this.name = name; + return this; + } + + public Builder setDescription(GraphQLInputParameter description) { + this.description = description; + return this; + } + + + public SomeObject build() { + return new SomeObject(name, description); + } + + } +} diff --git a/src/test/resources/schemas/input-wrapper.graphqls b/src/test/resources/schemas/input-wrapper.graphqls new file mode 100644 index 000000000..66de21a2b --- /dev/null +++ b/src/test/resources/schemas/input-wrapper.graphqls @@ -0,0 +1,23 @@ +# This input has all possible types +input InputWithDefaults { + floatVal: Float = 1.23 + booleanVal: Boolean = false + intVal: Int = 42 + stringVal: String = "my-default" + enumVal: MyEnum = ONE + nonNullEnumVal: MyEnum! = TWO + objectWithNullDefault: SomeObject = null + objectWithNonNullDefault: SomeObject = { name: "Bob" } + intList: [Int] = [1, 2, 3] + intListEmptyDefault: [Int] = [] + objectListEmptyDefault: [SomeObject]! = [] +} + +input SomeObject { + name: String! + description: String +} + +enum MyEnum { + ONE, TWO, THREE +} \ No newline at end of file From 834fd523a728ecc3e5b82eccdb14bc6b6c5295ba Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Tue, 16 Jan 2024 14:03:46 +0100 Subject: [PATCH 08/18] cleanup for PR --- .../codegen/kotlin/KotlinGraphQLTypeMapper.java | 2 -- .../graphql/codegen/mapper/DataModelMapper.java | 2 +- .../codegen/mapper/GraphQLTypeMapper.java | 17 +++++++++++++---- .../InputValueDefinitionToParameterMapper.java | 4 +--- .../graphql/codegen/model/MappingConfig.java | 6 +++++- .../graphql/codegen/model/MappingContext.java | 6 +++++- .../codegen/scala/ScalaGraphQLTypeMapper.java | 10 +++++----- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java index 69b8f8d25..4e90a381c 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java @@ -189,8 +189,6 @@ public String getResponseReturnType(MappingContext mappingContext, ExtendedField return getTypeConsideringPrimitive(mappingContext, namedDefinition, computedTypeName); } - static final boolean ENABLE_OPTIONAL_INPUT = true; - @Override public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { return getTypeConsideringPrimitive(mappingContext, namedDefinition, namedDefinition.getJavaName()); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java index 33ae20d51..d64b46d3a 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/DataModelMapper.java @@ -205,7 +205,7 @@ static String getParametrizedInputClassName(MappingContext mappingContext, * @param mappingContext Global mapping context * @return api package name if present. Generic package name otherwise */ - public static String getApiPackageName(MappingContext mappingContext) { + static String getApiPackageName(MappingContext mappingContext) { if (Utils.isNotBlank(mappingContext.getApiPackageName())) { return mappingContext.getApiPackageName(); } else { diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java index 7a9341d1c..77947bb94 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java @@ -4,7 +4,16 @@ import com.kobylynskyi.graphql.codegen.model.NamedDefinition; import com.kobylynskyi.graphql.codegen.model.RelayConfig; import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedFieldDefinition; -import graphql.language.*; +import graphql.language.Argument; +import graphql.language.Directive; +import graphql.language.DirectivesContainer; +import graphql.language.ListType; +import graphql.language.NamedNode; +import graphql.language.NonNullType; +import graphql.language.StringValue; +import graphql.language.Type; +import graphql.language.TypeName; +import graphql.language.InputValueDefinition; import java.util.Collections; import java.util.List; @@ -174,7 +183,7 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, Type gr NamedDefinition mappedCollectionType = getLanguageType(mappingContext, ((ListType) graphqlType).getType(), name, parentTypeName, false, true); if (mappedCollectionType.isInterfaceOrUnion() && - isInterfaceOrUnion(mappingContext, parentTypeName)) { + isInterfaceOrUnion(mappingContext, parentTypeName)) { mappedCollectionType.setJavaName( wrapSuperTypeIntoList(mappingContext, mappedCollectionType.getJavaName(), mandatory)); } else { @@ -218,7 +227,7 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, String gra } boolean serializeUsingObjectMapper = serializeFieldsUsingObjectMapper.contains(graphQLType) || - serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name); + serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name); return new NamedDefinition(langTypeName, graphQLType, isInterfaceOrUnion(mappingContext, graphQLType), mandatory, primitiveCanBeUsed, serializeUsingObjectMapper); @@ -263,7 +272,7 @@ public String getResponseReturnType(MappingContext mappingContext, protected boolean isInterfaceOrUnion(MappingContext mappingContext, String graphQLType) { return mappingContext.getInterfacesName().contains(graphQLType) || - mappingContext.getUnionsNames().contains(graphQLType); + mappingContext.getUnionsNames().contains(graphQLType); } public abstract String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java index 5396380af..8df2826f5 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java @@ -5,7 +5,7 @@ import com.kobylynskyi.graphql.codegen.model.ParameterDefinition; import com.kobylynskyi.graphql.codegen.model.builders.DeprecatedDefinitionBuilder; import com.kobylynskyi.graphql.codegen.utils.Utils; -import graphql.language.*; +import graphql.language.InputValueDefinition; import java.util.List; @@ -17,8 +17,6 @@ * @author kobylynskyi */ public class InputValueDefinitionToParameterMapper { - private static final String JAVA_UTIL_OPTIONAL = "java.util.Optional"; - private static final String JAVA_UTIL_LIST = "java.util.List"; private final ValueMapper valueMapper; private final GraphQLTypeMapper graphQLTypeMapper; private final AnnotationsMapper annotationsMapper; 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 6d1db45a6..f172b5c80 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfig.java @@ -1,7 +1,11 @@ package com.kobylynskyi.graphql.codegen.model; import java.io.File; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.Function; /** diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java index c4c17bf80..0f958e780 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java @@ -6,7 +6,11 @@ import com.kobylynskyi.graphql.codegen.model.definitions.*; import java.io.File; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; /** diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java index e97772334..5772e671c 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java @@ -65,17 +65,17 @@ public String wrapApiReturnTypeIfRequired(MappingContext mappingContext, } if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableReturnTypes()) - && !namedDefinition.isMandatory() - && !computedTypeName.startsWith(SCALA_UTIL_LIST) - && !computedTypeName.startsWith(JAVA_UTIL_LIST) - && !computedTypeName.startsWith(SCALA_UTIL_OPTIONAL)) { + && !namedDefinition.isMandatory() + && !computedTypeName.startsWith(SCALA_UTIL_LIST) + && !computedTypeName.startsWith(JAVA_UTIL_LIST) + && !computedTypeName.startsWith(SCALA_UTIL_OPTIONAL)) { // Kotlin/Scala: primitive types is Option by default // wrap the type into scala.Option (except java list and scala list) computedTypeName = getGenericsString(mappingContext, SCALA_UTIL_OPTIONAL, computedTypeName); } if (computedTypeName.startsWith(SCALA_UTIL_LIST) && - Utils.isNotBlank(mappingContext.getApiReturnListType())) { + Utils.isNotBlank(mappingContext.getApiReturnListType())) { // in case it is query/mutation, return type is list and apiReturnListType is set if (mappingContext.getApiReturnListType().contains(MappingConfigConstants.API_RETURN_NAME_PLACEHOLDER)) { Matcher matcher = SCALA_UTIL_LIST_ELEMENT_REGEX.matcher(computedTypeName); From 88e12d721b07f322ddc50799733d0e9848a63888 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Tue, 16 Jan 2024 14:16:04 +0100 Subject: [PATCH 09/18] fix build error --- .../codegen/gradle/GraphQLCodegenGradleTask.java | 13 +++++++++++++ .../graphql/codegen/GraphQLCodegenMojo.java | 2 +- .../codegen/model/MappingConfigConstants.java | 4 ++-- .../MappingConfigDefaultValuesInitializer.java | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) 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 a3228c925..8dc4cc303 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 @@ -87,6 +87,7 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode private Boolean generateDataFetchingEnvironmentArgumentInApis = MappingConfigConstants.DEFAULT_GENERATE_DATA_FETCHING_ENV; private Boolean generateModelsForRootTypes = MappingConfigConstants.DEFAULT_GENERATE_MODELS_FOR_ROOT_TYPES; private Boolean useOptionalForNullableReturnTypes = MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES; + private Boolean useWrapperForNullableInputTypes = MappingConfigConstants.DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES; private Boolean generateApisWithThrowsException = MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_THROWS_EXCEPTION; private Boolean generateApisWithSuspendFunctions = MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_SUSPEND_FUNCTIONS; @@ -170,6 +171,7 @@ public void generate() throws Exception { mappingConfig.setGenerateImmutableModels(generateImmutableModels); mappingConfig.setGenerateToString(generateToString); mappingConfig.setUseOptionalForNullableReturnTypes(useOptionalForNullableReturnTypes); + mappingConfig.setUseWrapperForNullableInputTypes(useWrapperForNullableInputTypes); mappingConfig.setGenerateApisWithThrowsException(generateApisWithThrowsException); mappingConfig.setGenerateApisWithSuspendFunctions(generateApisWithSuspendFunctions); mappingConfig.setGenerateJacksonTypeIdResolver(generateJacksonTypeIdResolver); @@ -691,6 +693,17 @@ public void setUseOptionalForNullableReturnTypes(Boolean useOptionalForNullableR this.useOptionalForNullableReturnTypes = useOptionalForNullableReturnTypes; } + @Input + @Optional + @Override + public Boolean getUseWrapperForNullableInputTypes() { + return useWrapperForNullableInputTypes; + } + + public void setUseWrapperForNullableInputTypes(Boolean useWrapperForNullableInputTypes) { + this.useWrapperForNullableInputTypes = useWrapperForNullableInputTypes; + } + @Input @Optional @Override 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 281487339..b1fb3e045 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 @@ -153,7 +153,7 @@ public class GraphQLCodegenMojo extends AbstractMojo implements GraphQLCodegenCo @Parameter(defaultValue = MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES_STRING) private boolean useOptionalForNullableReturnTypes; - @Parameter(defaultValue = MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES_STRING) + @Parameter(defaultValue = MappingConfigConstants.DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES_STRING) private boolean useWrapperForNullableInputTypes; @Parameter(defaultValue = MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_THROWS_EXCEPTION_STRING) diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java index 9818010f0..c16b53ab1 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigConstants.java @@ -52,8 +52,8 @@ public class MappingConfigConstants { public static final boolean DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES = false; public static final String DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES_STRING = "false"; - public static final boolean DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES = false; - public static final String DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES_STRING = "false"; + public static final boolean DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES = false; + public static final String DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES_STRING = "false"; public static final ApiNamePrefixStrategy DEFAULT_API_NAME_PREFIX_STRATEGY = ApiNamePrefixStrategy.CONSTANT; public static final String DEFAULT_API_NAME_PREFIX_STRATEGY_STRING = "CONSTANT"; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java index 956087385..a5ba391d9 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingConfigDefaultValuesInitializer.java @@ -89,7 +89,7 @@ public static void initDefaultValues(MappingConfig mappingConfig) { } if (mappingConfig.getUseWrapperForNullableInputTypes() == null) { mappingConfig.setUseWrapperForNullableInputTypes( - MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_INPUT_TYPES); + MappingConfigConstants.DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES); } if (mappingConfig.getApiNamePrefixStrategy() == null) { mappingConfig.setApiNamePrefixStrategy(MappingConfigConstants.DEFAULT_API_NAME_PREFIX_STRATEGY); From 0a1b94d74b00fdbe51824dc9e758ab895f9a8203 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Tue, 16 Jan 2024 14:42:32 +0100 Subject: [PATCH 10/18] cleanup code style --- .../generators/FilesGeneratorsFactory.java | 13 ++++++++++++- .../generators/impl/InputWrapperGenerator.java | 15 ++++++++++++--- .../codegen/java/JavaGraphQLTypeMapper.java | 7 +++++-- .../kotlin/KotlinGraphQLTypeMapper.java | 15 +++++++++------ .../codegen/mapper/GraphQLTypeMapper.java | 9 ++++++--- .../InputValueDefinitionToParameterMapper.java | 18 ++++++++++++------ .../graphql/codegen/model/MappingContext.java | 7 ++++++- .../codegen/scala/ScalaGraphQLTypeMapper.java | 17 ++++++++++------- 8 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java index ad1efe622..ef2e53449 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java @@ -1,6 +1,17 @@ package com.kobylynskyi.graphql.codegen.generators; -import com.kobylynskyi.graphql.codegen.generators.impl.*; +import com.kobylynskyi.graphql.codegen.generators.impl.EnumsGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.FieldResolversGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.InputGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.InputWrapperGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.InterfaceGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.JacksonTypeIdResolverGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.OperationsGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.ParametrizedInputGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.RequestResponseGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.ResponseProjectionGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.TypeGenerator; +import com.kobylynskyi.graphql.codegen.generators.impl.UnionGenerator; import com.kobylynskyi.graphql.codegen.mapper.DataModelMapperFactory; import com.kobylynskyi.graphql.codegen.model.MappingContext; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java index 9f57766ba..5aab4af56 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java @@ -7,9 +7,18 @@ import com.kobylynskyi.graphql.codegen.model.MappingContext; import java.io.File; -import java.util.*; - -import static com.kobylynskyi.graphql.codegen.model.DataModelFields.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static com.kobylynskyi.graphql.codegen.model.DataModelFields.CLASS_NAME; +import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_ANNOTATION; +import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_INFO; +import static com.kobylynskyi.graphql.codegen.model.DataModelFields.IMPORTS; +import static com.kobylynskyi.graphql.codegen.model.DataModelFields.NAME; +import static com.kobylynskyi.graphql.codegen.model.DataModelFields.PACKAGE; /** * Generates files for inputs diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java index 8f1ff1559..5ab543a5a 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java @@ -130,7 +130,8 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, String gra } @Override - public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { + public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + String parentTypeName) { String computedTypeName = namedDefinition.getJavaName(); if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes()) && mappingContext.getInputsName().contains(parentTypeName) && @@ -142,7 +143,9 @@ public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDef } @Override - public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { + public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + InputValueDefinition inputValueDefinition, String defaultValue, + String parentTypeName) { if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes()) && mappingContext.getInputsName().contains(parentTypeName) && !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST)) { diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java index 4e90a381c..ac04b7616 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/kotlin/KotlinGraphQLTypeMapper.java @@ -91,12 +91,12 @@ public String wrapApiReturnTypeIfRequired(MappingContext mappingContext, String computedTypeName = getTypeConsideringPrimitive(mappingContext, namedDefinition, namedDefinition.getJavaName()); if (parentTypeName.equalsIgnoreCase(GraphQLOperation.SUBSCRIPTION.name()) && - Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { + Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { // in case it is subscription and subscriptionReturnType is set return getGenericsString(mappingContext, mappingContext.getSubscriptionReturnType(), computedTypeName); } if (computedTypeName.startsWith(KOTLIN_UTIL_LIST) && - Utils.isNotBlank(mappingContext.getApiReturnListType())) { + Utils.isNotBlank(mappingContext.getApiReturnListType())) { // in case it is query/mutation, return type is list and apiReturnListType is set if (mappingContext.getApiReturnListType().contains(MappingConfigConstants.API_RETURN_NAME_PLACEHOLDER)) { boolean isNullable = computedTypeName.endsWith(KOTLIN_UTIL_NULLABLE); @@ -160,12 +160,12 @@ public String getTypeConsideringPrimitive(MappingContext mappingContext, String modelClassNameWithPrefixAndSuffix = DataModelMapper .getModelClassNameWithPrefixAndSuffix(mappingContext, graphqlTypeName); if (computedTypeName.contains(modelClassNameWithPrefixAndSuffix + KOTLIN_UTIL_NULLABLE) || - computedTypeName.contains(graphqlTypeName + KOTLIN_UTIL_NULLABLE)) { + computedTypeName.contains(graphqlTypeName + KOTLIN_UTIL_NULLABLE)) { return computedTypeName; } if (!computedTypeName .contains(modelClassNameWithPrefixAndSuffix + KOTLIN_UTIL_NULLABLE) && computedTypeName - .contains(modelClassNameWithPrefixAndSuffix)) { + .contains(modelClassNameWithPrefixAndSuffix)) { return computedTypeName.replace(modelClassNameWithPrefixAndSuffix, modelClassNameWithPrefixAndSuffix + KOTLIN_UTIL_NULLABLE); } @@ -190,12 +190,15 @@ public String getResponseReturnType(MappingContext mappingContext, ExtendedField } @Override - public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { + public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + String parentTypeName) { return getTypeConsideringPrimitive(mappingContext, namedDefinition, namedDefinition.getJavaName()); } @Override - public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { + public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + InputValueDefinition inputValueDefinition, String defaultValue, + String parentTypeName) { return defaultValue; } } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java index 77947bb94..af757c52f 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java @@ -7,13 +7,13 @@ import graphql.language.Argument; import graphql.language.Directive; import graphql.language.DirectivesContainer; +import graphql.language.InputValueDefinition; import graphql.language.ListType; import graphql.language.NamedNode; import graphql.language.NonNullType; import graphql.language.StringValue; import graphql.language.Type; import graphql.language.TypeName; -import graphql.language.InputValueDefinition; import java.util.Collections; import java.util.List; @@ -275,7 +275,10 @@ protected boolean isInterfaceOrUnion(MappingContext mappingContext, String graph mappingContext.getUnionsNames().contains(graphQLType); } - public abstract String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName); + public abstract String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + String parentTypeName); - public abstract String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName); + public abstract String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + InputValueDefinition inputValueDefinition, String defaultValue, + String parentTypeName); } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java index 8df2826f5..613f1d7e9 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/InputValueDefinitionToParameterMapper.java @@ -61,10 +61,13 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit ParameterDefinition parameter = new ParameterDefinition(); parameter.setName(dataModelMapper.capitalizeIfRestricted(mappingContext, inputValueDefinition.getName())); parameter.setOriginalName(inputValueDefinition.getName()); - parameter.setType(graphQLTypeMapper.wrapApiInputTypeIfRequired(mappingContext, namedDefinition, parentTypeName)); - parameter.setDefaultValue(getDefaultValue(mappingContext, inputValueDefinition, parentTypeName, namedDefinition)); + parameter.setType(graphQLTypeMapper.wrapApiInputTypeIfRequired(mappingContext, namedDefinition, + parentTypeName)); + parameter.setDefaultValue(getDefaultValue(mappingContext, inputValueDefinition, parentTypeName, + namedDefinition)); parameter.setVisibility(Utils.getFieldVisibility(mappingContext)); - parameter.setAnnotations(annotationsMapper.getAnnotations(mappingContext, inputValueDefinition.getType(), inputValueDefinition, parentTypeName, false)); + parameter.setAnnotations(annotationsMapper.getAnnotations(mappingContext, inputValueDefinition.getType(), + inputValueDefinition, parentTypeName, false)); parameter.setDeprecated(DeprecatedDefinitionBuilder.build(mappingContext, inputValueDefinition)); parameter.setMandatory(namedDefinition.isMandatory()); parameter.setSerializeUsingObjectMapper(namedDefinition.isSerializeUsingObjectMapper()); @@ -73,9 +76,12 @@ private ParameterDefinition map(MappingContext mappingContext, InputValueDefinit return parameter; } - private String getDefaultValue(MappingContext mappingContext, InputValueDefinition inputValueDefinition, String parentTypeName, NamedDefinition namedDefinition) { - String value = valueMapper.map(mappingContext, inputValueDefinition.getDefaultValue(), inputValueDefinition.getType()); - return graphQLTypeMapper.wrapApiDefaultValueIfRequired(mappingContext, namedDefinition, inputValueDefinition, value, parentTypeName); + private String getDefaultValue(MappingContext mappingContext, InputValueDefinition inputValueDefinition, + String parentTypeName, NamedDefinition namedDefinition) { + String value = valueMapper.map(mappingContext, inputValueDefinition.getDefaultValue(), + inputValueDefinition.getType()); + return graphQLTypeMapper.wrapApiDefaultValueIfRequired(mappingContext, namedDefinition, inputValueDefinition, + value, parentTypeName); } } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java index 0f958e780..937d07cb6 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/MappingContext.java @@ -3,7 +3,12 @@ import com.kobylynskyi.graphql.codegen.mapper.DataModelMapper; import com.kobylynskyi.graphql.codegen.mapper.DataModelMapperFactory; import com.kobylynskyi.graphql.codegen.mapper.FieldDefinitionToParameterMapper; -import com.kobylynskyi.graphql.codegen.model.definitions.*; +import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDefinition; +import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedDocument; +import com.kobylynskyi.graphql.codegen.model.definitions.ExtendedEnumTypeDefinition; +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 java.io.File; import java.util.HashMap; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java index 5772e671c..e29aa3463 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/scala/ScalaGraphQLTypeMapper.java @@ -65,17 +65,17 @@ public String wrapApiReturnTypeIfRequired(MappingContext mappingContext, } if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableReturnTypes()) - && !namedDefinition.isMandatory() - && !computedTypeName.startsWith(SCALA_UTIL_LIST) - && !computedTypeName.startsWith(JAVA_UTIL_LIST) - && !computedTypeName.startsWith(SCALA_UTIL_OPTIONAL)) { + && !namedDefinition.isMandatory() + && !computedTypeName.startsWith(SCALA_UTIL_LIST) + && !computedTypeName.startsWith(JAVA_UTIL_LIST) + && !computedTypeName.startsWith(SCALA_UTIL_OPTIONAL)) { // Kotlin/Scala: primitive types is Option by default // wrap the type into scala.Option (except java list and scala list) computedTypeName = getGenericsString(mappingContext, SCALA_UTIL_OPTIONAL, computedTypeName); } if (computedTypeName.startsWith(SCALA_UTIL_LIST) && - Utils.isNotBlank(mappingContext.getApiReturnListType())) { + Utils.isNotBlank(mappingContext.getApiReturnListType())) { // in case it is query/mutation, return type is list and apiReturnListType is set if (mappingContext.getApiReturnListType().contains(MappingConfigConstants.API_RETURN_NAME_PLACEHOLDER)) { Matcher matcher = SCALA_UTIL_LIST_ELEMENT_REGEX.matcher(computedTypeName); @@ -118,12 +118,15 @@ public String getGenericsString(MappingContext mappingContext, String genericTyp } @Override - public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName) { + public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + String parentTypeName) { return getTypeConsideringPrimitive(mappingContext, namedDefinition, namedDefinition.getJavaName()); } @Override - public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { + public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + InputValueDefinition inputValueDefinition, String defaultValue, + String parentTypeName) { return defaultValue; } From 8bcfce64aee260c4bd02c5f6f0e9a729ec676f21 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Tue, 16 Jan 2024 14:50:44 +0100 Subject: [PATCH 11/18] cleanup code style --- .../codegen/gradle/GraphQLCodegenGradleTask.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) 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 8dc4cc303..250b80423 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 @@ -87,7 +87,8 @@ public class GraphQLCodegenGradleTask extends DefaultTask implements GraphQLCode private Boolean generateDataFetchingEnvironmentArgumentInApis = MappingConfigConstants.DEFAULT_GENERATE_DATA_FETCHING_ENV; private Boolean generateModelsForRootTypes = MappingConfigConstants.DEFAULT_GENERATE_MODELS_FOR_ROOT_TYPES; private Boolean useOptionalForNullableReturnTypes = MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES; - private Boolean useWrapperForNullableInputTypes = MappingConfigConstants.DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES; + private Boolean useWrapperForNullableInputTypes = + MappingConfigConstants.DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES; private Boolean generateApisWithThrowsException = MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_THROWS_EXCEPTION; private Boolean generateApisWithSuspendFunctions = MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_SUSPEND_FUNCTIONS; @@ -147,7 +148,7 @@ public void generate() throws Exception { mappingConfig.setCustomAnnotationsMapping( customAnnotationsMapping != null ? customAnnotationsMapping : new HashMap<>()); mappingConfig.setCustomTemplatesRoot( - customTemplatesRoot != null ? customTemplatesRoot : getProject().getProjectDir() + customTemplatesRoot != null ? customTemplatesRoot : getProject().getProjectDir() ); mappingConfig.setCustomTemplates( customTemplates != null ? customTemplates : new HashMap<>()); @@ -238,10 +239,10 @@ private GraphQLCodegen instantiateCodegen(MappingConfig mappingConfig) throws IO if (skipSchemaSizeLimit) { ParserOptions.Builder parserOptionBuilder = ParserOptions.newParserOptions() - .maxTokens(Integer.MAX_VALUE) - .maxCharacters(Integer.MAX_VALUE) - .maxWhitespaceTokens(Integer.MAX_VALUE) - .maxRuleDepth(Integer.MAX_VALUE); + .maxTokens(Integer.MAX_VALUE) + .maxCharacters(Integer.MAX_VALUE) + .maxWhitespaceTokens(Integer.MAX_VALUE) + .maxRuleDepth(Integer.MAX_VALUE); ParserOptions.setDefaultParserOptions(parserOptionBuilder.build()); } switch (language) { From dd8ea354fc2ea1074f22edcae534b445f5046bdd Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Tue, 16 Jan 2024 14:52:42 +0100 Subject: [PATCH 12/18] cleanup code style --- .../GraphQLCodegenInputWrapperTest.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java index 57fd6f4e8..795f94c58 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java @@ -39,20 +39,26 @@ void cleanup() { @Test void generate_CheckFiles() throws Exception { - generate("src/test/resources/schemas/input-wrapper.graphqls"); + generate(); File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles()); List generatedFileNames = Arrays.stream(files).map(File::getName).sorted().collect(toList()); - assertEquals(asList("GraphQLInputParameter.java", "InputWithDefaults.java", "MyEnum.java", "SomeObject.java"), generatedFileNames); + assertEquals(asList( + "GraphQLInputParameter.java", + "InputWithDefaults.java", + "MyEnum.java", + "SomeObject.java" + ), generatedFileNames); for (File file : files) { - assertSameTrimmedContent(new File(String.format("src/test/resources/expected-classes/input-wrapper/%s.txt", - file.getName())), file); + assertSameTrimmedContent(new File( + String.format("src/test/resources/expected-classes/input-wrapper/%s.txt", file.getName())), + file); } } - private void generate(String path) throws IOException { - new JavaGraphQLCodegen(singletonList(path), + private void generate() throws IOException { + new JavaGraphQLCodegen(singletonList("src/test/resources/schemas/input-wrapper.graphqls"), outputBuildDir, mappingConfig, TestUtils.getStaticGeneratedInfo(mappingConfig)).generate(); } From da664558f25925bdbdb65262912bd4cb259d073f Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Wed, 17 Jan 2024 10:04:15 +0100 Subject: [PATCH 13/18] update SBT codegen. General code clean. --- .../graphql/codegen/GraphQLCodegenKeys.scala | 2 + .../codegen/GraphQLCodegenPlugin.scala | 2 + .../codegen/java/JavaGraphQLTypeMapper.java | 9 ++- .../codegen/mapper/GraphQLTypeMapper.java | 61 +++++++++++++++++-- .../model/GraphQLCodegenConfiguration.java | 4 +- 5 files changed, 67 insertions(+), 11 deletions(-) diff --git a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala index 58b488341..33a5b080a 100644 --- a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala +++ b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenKeys.scala @@ -133,6 +133,8 @@ trait GraphQLCodegenKeys { val useOptionalForNullableReturnTypes = settingKey[Boolean]("useOptionalForNullableReturnTypes") + val useWrapperForNullableInputTypes = settingKey[Boolean]("useWrapperForNullableInputTypes") + val generateApisWithThrowsException = settingKey[Boolean]("generateApisWithThrowsException") val graphqlQueryIntrospectionResultPath = settingKey[Option[String]]("graphqlQueryIntrospectionResultPath") diff --git a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala index b4657856a..265b92e21 100644 --- a/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala +++ b/plugins/sbt/graphql-java-codegen-sbt-plugin/src/main/scala/io/github/dreamylost/graphql/codegen/GraphQLCodegenPlugin.scala @@ -100,6 +100,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co apiReturnListType := None, apiInterfaceStrategy := MappingConfigConstants.DEFAULT_API_INTERFACE_STRATEGY, useOptionalForNullableReturnTypes := MappingConfigConstants.DEFAULT_USE_OPTIONAL_FOR_NULLABLE_RETURN_TYPES, + useWrapperForNullableInputTypes := MappingConfigConstants.DEFAULT_USE_WRAPPER_FOR_NULLABLE_INPUT_TYPES, generateApisWithThrowsException := MappingConfigConstants.DEFAULT_GENERATE_APIS_WITH_THROWS_EXCEPTION, addGeneratedAnnotation := MappingConfigConstants.DEFAULT_ADD_GENERATED_ANNOTATION, generatedAnnotation := None, @@ -191,6 +192,7 @@ class GraphQLCodegenPlugin(configuration: Configuration, private[codegen] val co mappingConfig.setDirectiveAnnotationsMapping((GraphQLCodegenConfig / directiveAnnotationsMapping).value) mappingConfig.setApiInterfaceStrategy((GraphQLCodegenConfig / apiInterfaceStrategy).value) mappingConfig.setUseOptionalForNullableReturnTypes((GraphQLCodegenConfig / useOptionalForNullableReturnTypes).value) + mappingConfig.setUseWrapperForNullableInputTypes((GraphQLCodegenConfig / useWrapperForNullableInputTypes).value) mappingConfig.setGenerateApisWithThrowsException((GraphQLCodegenConfig / generateApisWithThrowsException).value) mappingConfig.setAddGeneratedAnnotation((GraphQLCodegenConfig / addGeneratedAnnotation).value) mappingConfig.setGeneratedAnnotation((GraphQLCodegenConfig / generatedAnnotation).value.orNull) diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java index 5ab543a5a..ae9cfc4d3 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java @@ -27,6 +27,9 @@ public class JavaGraphQLTypeMapper extends GraphQLTypeMapper { public static final Pattern JAVA_UTIL_LIST_ELEMENT_REGEX = Pattern.compile("java\\.util\\.List<(.+)>"); private static final String JAVA_UTIL_OPTIONAL = "java.util.Optional"; private static final String INPUT_WRAPPER_CLASS = "GraphQLInputParameter"; + private static final String INPUT_WRAPPER_NULL = INPUT_WRAPPER_CLASS + ".withNull()"; + private static final String INPUT_WRAPPER_UNDEFINED = INPUT_WRAPPER_CLASS + ".undefined()"; + private static final String INPUT_WRAPPER_WITH_VALUE = INPUT_WRAPPER_CLASS + ".withValue(%s)"; private static final Set JAVA_PRIMITIVE_TYPES = new HashSet<>(asList( "byte", "short", "int", "long", "float", "double", "char", "boolean")); @@ -150,11 +153,11 @@ public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, Named mappingContext.getInputsName().contains(parentTypeName) && !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST)) { if (defaultValue == null) { - return INPUT_WRAPPER_CLASS + ".undefined()"; + return INPUT_WRAPPER_UNDEFINED; } else if (inputValueDefinition.getDefaultValue() instanceof NullValue) { - return INPUT_WRAPPER_CLASS + ".withNull()"; + return INPUT_WRAPPER_NULL; } else { - return INPUT_WRAPPER_CLASS + ".withValue(" + defaultValue + ")"; + return String.format(INPUT_WRAPPER_WITH_VALUE, defaultValue); } } else { return defaultValue; diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java index af757c52f..d931bf475 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java @@ -113,6 +113,61 @@ public abstract String wrapApiReturnTypeIfRequired(MappingContext mappingContext NamedDefinition namedDefinition, String parentTypeName); + /** + * Wraps type into GraphQLInputParameter, if required. + * + *

Example 1: + * * Given GraphQL schema: {@code input MyInput { name: String! }} + * * Given config: {@code useWrapperForNullableInputTypes = true} + * * Return: {@code String} + * + *

Example 2: + * * Given GraphQL schema: {@code input MyInput { name: String }} + * * Given config: {@code useWrapperForNullableInputTypes = true} + * * Return: {@code GraphQLInputParameter} + * + *

Example 2: + * * Given GraphQL schema: {@code input MyInput { name: String[] }} + * * Given config: {@code useWrapperForNullableInputTypes = true} + * * Return: {@code List} + * + * @param mappingContext Global mapping context + * @param namedDefinition Named definition + * @param parentTypeName Name of the parent type + * @return Java type wrapped into GraphQLInputParameter + */ + public abstract String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + String parentTypeName); + + /** + * Wraps type into GraphQLInputParameter, if required. + * + *

Example 1: + * * Given GraphQL schema: {@code input MyInput { name: String }} + * * Given config: {@code useWrapperForNullableInputTypes = true} + * * Return: {@code GraphQLInputParameter.undefined()} + * + *

Example 2: + * * Given GraphQL schema: {@code input MyInput { name: String = null }} + * * Given config: {@code useWrapperForNullableInputTypes = true} + * * Return: {@code GraphQLInputParameter.withNull()} + * + *

Example 2: + * * Given GraphQL schema: {@code input MyInput { name: String = "some value" }} + * * Given config: {@code useWrapperForNullableInputTypes = true} + * * Return: {@code GraphQLInputParameter.withValue("some value")} + * + * @param mappingContext Global mapping context + * @param namedDefinition Named definition + * @param inputValueDefinition Input value definition + * @param defaultValue Default value + * @param parentTypeName Name of the parent type + * @return Java type wrapped into GraphQLInputParameter + */ + public abstract String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, + InputValueDefinition inputValueDefinition, String defaultValue, + String parentTypeName); + /** * Check if the time is primitive. * @@ -275,10 +330,4 @@ protected boolean isInterfaceOrUnion(MappingContext mappingContext, String graph mappingContext.getUnionsNames().contains(graphQLType); } - public abstract String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, - String parentTypeName); - - public abstract String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, - InputValueDefinition inputValueDefinition, String defaultValue, - String parentTypeName); } 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 a56ae33e4..6480da870 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java @@ -357,9 +357,9 @@ public interface GraphQLCodegenConfiguration { Boolean getUseOptionalForNullableReturnTypes(); /** - * Specifies whether input types of generated API interface should be wrapped into java.util.Optional + * Specifies whether input types of generated Java input classes should be wrapped into GraphQLInputParameter * - * @return true if input types should be wrapped into java.util.Optional + * @return true if input types should be wrapped into GraphQLInputParameter */ Boolean getUseWrapperForNullableInputTypes(); From 9ad5b73ce1670cbe6f940ea835fe42aace423f14 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Wed, 17 Jan 2024 10:08:25 +0100 Subject: [PATCH 14/18] code style --- .../graphql/codegen/model/GraphQLCodegenConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 6480da870..d1c4c45b1 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java @@ -357,7 +357,8 @@ public interface GraphQLCodegenConfiguration { Boolean getUseOptionalForNullableReturnTypes(); /** - * Specifies whether input types of generated Java input classes should be wrapped into GraphQLInputParameter + * Specifies whether input types of generated input classes should be wrapped into + * GraphQLInputParameter. * * @return true if input types should be wrapped into GraphQLInputParameter */ From e6933bbb7d10f5f9e53fb75a790ee10e6fefdaff Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Wed, 17 Jan 2024 13:51:21 +0100 Subject: [PATCH 15/18] update documentation --- docs/codegen-options.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/codegen-options.md b/docs/codegen-options.md index 263b9d32b..f5851a3b9 100644 --- a/docs/codegen-options.md +++ b/docs/codegen-options.md @@ -44,6 +44,7 @@ | `generateExtensionFieldsResolvers` | Boolean | False | Specifies whether all fields in extensions (`extend type` and `extend interface`) should be present in Resolver interface instead of the type class itself. | | `generateModelsForRootTypes` | Boolean | False | Specifies whether model classes should be generated for `type Query`, `type Subscription`, `type Mutation`. | | `useOptionalForNullableReturnTypes` | Boolean | False | Specifies whether nullable return types of api methods should be wrapped into [`java.util.Optional<>`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Optional.html). Lists will not be wrapped. | +| `useWrapperForNullableInputTypes` | Boolean | False | Specifies whether nullable parameters on input types should be wrapped into [`GraphQLInputParameter<>`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Optional.html). Wrapping enables differentiation between an input parameter that is not defined and one that is explicitly null. Lists will not be wrapped. | | `generateApisWithThrowsException` | Boolean | True | Specifies whether api interface methods should have `throws Exception` in signature. | | `generateApisWithSuspendFunctions` | Boolean | False | Specifies whether api interface methods should have `suspend` modifier in signature. Only supported in Kotlin. | | `generateNoArgsConstructorOnly` | Boolean | False | Specifies whether model classes should only have a no-args constructor. All-args constructor will not be generated in case value is true | @@ -69,7 +70,7 @@ | `supportUnknownFields` | Boolean | False | Specifies whether api classes should support unknown fields during serialization or deserialization. If `true`, classes will include a property of type [`java.util.Map`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Map.html) that will store unknown fields. | | `unknownFieldsPropertyName` | String | userDefinedFields | Specifies the name of the property to be included in api classes to support unknown fields during serialization or deserialization | | `skip` | Boolean | False | If true, then code generation will not happen | -| `skipSchemaSizeLimit` | Boolean | True | When set to true, the GraphQL schema will be processed with token, character, line and rule depth limits. Set to false to process the schema regardless of its size. +| `skipSchemaSizeLimit` | Boolean | True | When set to true, the GraphQL schema will be processed with token, character, line and rule depth limits. Set to false to process the schema regardless of its size. | From e112eb8db194c7951962f90bb0bb8945a16c8bc3 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Wed, 17 Jan 2024 16:43:44 +0100 Subject: [PATCH 16/18] Update feature from generating GraphQLInputParameter, to relying on ArgumentValue from org.springframework.graphql.data --- docs/codegen-options.md | 2 +- .../generators/FilesGeneratorsFactory.java | 2 - .../generators/FreeMarkerTemplateType.java | 3 +- .../impl/InputWrapperGenerator.java | 56 --------- .../codegen/java/JavaGraphQLTypeMapper.java | 28 ++--- .../codegen/mapper/GraphQLTypeMapper.java | 22 ++-- .../model/GraphQLCodegenConfiguration.java | 4 +- .../java-lang/graphql_input_parameter.ftl | 111 ------------------ .../kotlin-lang/graphql_input_parameter.ftl | 0 .../scala-lang/graphql_input_parameter.ftl | 0 .../GraphQLCodegenInputWrapperTest.java | 1 - .../GraphQLInputParameter.java.txt | 103 ---------------- .../input-wrapper/InputWithDefaults.java.txt | 72 ++++++------ .../input-wrapper/SomeObject.java.txt | 12 +- 14 files changed, 71 insertions(+), 345 deletions(-) delete mode 100644 src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java delete mode 100644 src/main/resources/templates/java-lang/graphql_input_parameter.ftl delete mode 100644 src/main/resources/templates/kotlin-lang/graphql_input_parameter.ftl delete mode 100644 src/main/resources/templates/scala-lang/graphql_input_parameter.ftl delete mode 100644 src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt diff --git a/docs/codegen-options.md b/docs/codegen-options.md index f5851a3b9..33724f565 100644 --- a/docs/codegen-options.md +++ b/docs/codegen-options.md @@ -44,7 +44,7 @@ | `generateExtensionFieldsResolvers` | Boolean | False | Specifies whether all fields in extensions (`extend type` and `extend interface`) should be present in Resolver interface instead of the type class itself. | | `generateModelsForRootTypes` | Boolean | False | Specifies whether model classes should be generated for `type Query`, `type Subscription`, `type Mutation`. | | `useOptionalForNullableReturnTypes` | Boolean | False | Specifies whether nullable return types of api methods should be wrapped into [`java.util.Optional<>`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Optional.html). Lists will not be wrapped. | -| `useWrapperForNullableInputTypes` | Boolean | False | Specifies whether nullable parameters on input types should be wrapped into [`GraphQLInputParameter<>`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Optional.html). Wrapping enables differentiation between an input parameter that is not defined and one that is explicitly null. Lists will not be wrapped. | +| `useWrapperForNullableInputTypes` | Boolean | False | Specifies whether nullable parameters on input types should be wrapped into [`ArgumentValue<>`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Optional.html). This requires org.springframework.graphql.data version 1.1.0+. Lists will not be wrapped. | | `generateApisWithThrowsException` | Boolean | True | Specifies whether api interface methods should have `throws Exception` in signature. | | `generateApisWithSuspendFunctions` | Boolean | False | Specifies whether api interface methods should have `suspend` modifier in signature. Only supported in Kotlin. | | `generateNoArgsConstructorOnly` | Boolean | False | Specifies whether model classes should only have a no-args constructor. All-args constructor will not be generated in case value is true | diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java index ef2e53449..a444d4536 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FilesGeneratorsFactory.java @@ -3,7 +3,6 @@ import com.kobylynskyi.graphql.codegen.generators.impl.EnumsGenerator; import com.kobylynskyi.graphql.codegen.generators.impl.FieldResolversGenerator; import com.kobylynskyi.graphql.codegen.generators.impl.InputGenerator; -import com.kobylynskyi.graphql.codegen.generators.impl.InputWrapperGenerator; import com.kobylynskyi.graphql.codegen.generators.impl.InterfaceGenerator; import com.kobylynskyi.graphql.codegen.generators.impl.JacksonTypeIdResolverGenerator; import com.kobylynskyi.graphql.codegen.generators.impl.OperationsGenerator; @@ -42,7 +41,6 @@ public static List getAll(MappingContext context, generators.add(new ResponseProjectionGenerator(context, dataModelMapperFactory)); generators.add(new ParametrizedInputGenerator(context, dataModelMapperFactory)); generators.add(new FieldResolversGenerator(context, dataModelMapperFactory)); - generators.add(new InputWrapperGenerator(context)); generators.add(new InputGenerator(context, dataModelMapperFactory)); generators.add(new UnionGenerator(context, dataModelMapperFactory)); generators.add(new RequestResponseGenerator(context, dataModelMapperFactory)); diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java index a0a788a17..87229e4f4 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/generators/FreeMarkerTemplateType.java @@ -14,7 +14,6 @@ public enum FreeMarkerTemplateType { OPERATIONS, PARAMETRIZED_INPUT, RESPONSE_PROJECTION, - JACKSON_TYPE_ID_RESOLVER, - GRAPHQL_INPUT_PARAMETER + JACKSON_TYPE_ID_RESOLVER } diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java b/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java deleted file mode 100644 index 5aab4af56..000000000 --- a/src/main/java/com/kobylynskyi/graphql/codegen/generators/impl/InputWrapperGenerator.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.kobylynskyi.graphql.codegen.generators.impl; - -import com.kobylynskyi.graphql.codegen.generators.FilesGenerator; -import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateFilesCreator; -import com.kobylynskyi.graphql.codegen.generators.FreeMarkerTemplateType; -import com.kobylynskyi.graphql.codegen.mapper.DataModelMapper; -import com.kobylynskyi.graphql.codegen.model.MappingContext; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static com.kobylynskyi.graphql.codegen.model.DataModelFields.CLASS_NAME; -import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_ANNOTATION; -import static com.kobylynskyi.graphql.codegen.model.DataModelFields.GENERATED_INFO; -import static com.kobylynskyi.graphql.codegen.model.DataModelFields.IMPORTS; -import static com.kobylynskyi.graphql.codegen.model.DataModelFields.NAME; -import static com.kobylynskyi.graphql.codegen.model.DataModelFields.PACKAGE; - -/** - * Generates files for inputs - */ -public class InputWrapperGenerator implements FilesGenerator { - - public static final String CLASS_NAME_GRAPHQL_INPUT_PARAMETER = "GraphQLInputParameter"; - private final MappingContext mappingContext; - - public InputWrapperGenerator(MappingContext mappingContext) { - this.mappingContext = mappingContext; - } - - @Override - public List generate() { - List generatedFiles = new ArrayList<>(); - if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes())) { - String packageName = DataModelMapper.getModelPackageName(mappingContext); - Set imports = DataModelMapper.getImports(mappingContext, packageName); - - Map dataModel = new HashMap<>(); - dataModel.put(NAME, CLASS_NAME_GRAPHQL_INPUT_PARAMETER); - dataModel.put(CLASS_NAME, CLASS_NAME_GRAPHQL_INPUT_PARAMETER); - dataModel.put(PACKAGE, packageName); - dataModel.put(IMPORTS, imports); - dataModel.put(GENERATED_ANNOTATION, mappingContext.getAddGeneratedAnnotation()); - dataModel.put(GENERATED_INFO, mappingContext.getGeneratedInformation()); - generatedFiles.add(FreeMarkerTemplateFilesCreator - .create(mappingContext, FreeMarkerTemplateType.GRAPHQL_INPUT_PARAMETER, dataModel)); - } - - return generatedFiles; - } - -} diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java index ae9cfc4d3..224ce6ac4 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/java/JavaGraphQLTypeMapper.java @@ -26,10 +26,10 @@ public class JavaGraphQLTypeMapper extends GraphQLTypeMapper { public static final String JAVA_UTIL_LIST = "java.util.List"; public static final Pattern JAVA_UTIL_LIST_ELEMENT_REGEX = Pattern.compile("java\\.util\\.List<(.+)>"); private static final String JAVA_UTIL_OPTIONAL = "java.util.Optional"; - private static final String INPUT_WRAPPER_CLASS = "GraphQLInputParameter"; - private static final String INPUT_WRAPPER_NULL = INPUT_WRAPPER_CLASS + ".withNull()"; - private static final String INPUT_WRAPPER_UNDEFINED = INPUT_WRAPPER_CLASS + ".undefined()"; - private static final String INPUT_WRAPPER_WITH_VALUE = INPUT_WRAPPER_CLASS + ".withValue(%s)"; + private static final String INPUT_WRAPPER_CLASS = "org.springframework.graphql.data.ArgumentValue"; + private static final String INPUT_WRAPPER_NULL = INPUT_WRAPPER_CLASS + ".ofNullable(null)"; + private static final String INPUT_WRAPPER_UNDEFINED = INPUT_WRAPPER_CLASS + ".omitted()"; + private static final String INPUT_WRAPPER_WITH_VALUE = INPUT_WRAPPER_CLASS + ".ofNullable(%s)"; private static final Set JAVA_PRIMITIVE_TYPES = new HashSet<>(asList( "byte", "short", "int", "long", "float", "double", "char", "boolean")); @@ -62,18 +62,18 @@ public String wrapApiReturnTypeIfRequired(MappingContext mappingContext, String parentTypeName) { String computedTypeName = namedDefinition.getJavaName(); if (parentTypeName.equalsIgnoreCase(GraphQLOperation.SUBSCRIPTION.name()) && - Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { + Utils.isNotBlank(mappingContext.getSubscriptionReturnType())) { // in case it is subscription and subscriptionReturnType is set return getGenericsString(mappingContext, mappingContext.getSubscriptionReturnType(), computedTypeName); } if (Boolean.TRUE.equals(mappingContext.getUseOptionalForNullableReturnTypes()) - && !namedDefinition.isMandatory() - && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + && !namedDefinition.isMandatory() + && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { computedTypeName = getGenericsString(mappingContext, JAVA_UTIL_OPTIONAL, computedTypeName); } if (computedTypeName.startsWith(JAVA_UTIL_LIST) && - Utils.isNotBlank(mappingContext.getApiReturnListType())) { + Utils.isNotBlank(mappingContext.getApiReturnListType())) { // in case it is query/mutation, return type is list and apiReturnListType is set if (mappingContext.getApiReturnListType().contains(MappingConfigConstants.API_RETURN_NAME_PLACEHOLDER)) { Matcher matcher = JAVA_UTIL_LIST_ELEMENT_REGEX.matcher(computedTypeName); @@ -123,8 +123,8 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, String gra langTypeName = DataModelMapper.getModelClassNameWithPrefixAndSuffix(mappingContext, graphQLType); } if (serializeFieldsUsingObjectMapper.contains(graphQLType) || - (name != null && parentTypeName != null && - serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name))) { + (name != null && parentTypeName != null && + serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name))) { serializeUsingObjectMapper = true; } @@ -137,8 +137,8 @@ public String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDef String parentTypeName) { String computedTypeName = namedDefinition.getJavaName(); if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes()) && - mappingContext.getInputsName().contains(parentTypeName) && - !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { + mappingContext.getInputsName().contains(parentTypeName) && + !namedDefinition.isMandatory() && !computedTypeName.startsWith(JAVA_UTIL_LIST)) { return getGenericsString(mappingContext, INPUT_WRAPPER_CLASS, computedTypeName); } @@ -150,8 +150,8 @@ public String wrapApiDefaultValueIfRequired(MappingContext mappingContext, Named InputValueDefinition inputValueDefinition, String defaultValue, String parentTypeName) { if (Boolean.TRUE.equals(mappingContext.getUseWrapperForNullableInputTypes()) && - mappingContext.getInputsName().contains(parentTypeName) && - !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST)) { + mappingContext.getInputsName().contains(parentTypeName) && + !namedDefinition.isMandatory() && !namedDefinition.getJavaName().startsWith(JAVA_UTIL_LIST)) { if (defaultValue == null) { return INPUT_WRAPPER_UNDEFINED; } else if (inputValueDefinition.getDefaultValue() instanceof NullValue) { diff --git a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java index d931bf475..d5d8318e4 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/mapper/GraphQLTypeMapper.java @@ -114,7 +114,7 @@ public abstract String wrapApiReturnTypeIfRequired(MappingContext mappingContext String parentTypeName); /** - * Wraps type into GraphQLInputParameter, if required. + * Wraps type into ArgumentValue, if required. * *

Example 1: * * Given GraphQL schema: {@code input MyInput { name: String! }} @@ -124,7 +124,7 @@ public abstract String wrapApiReturnTypeIfRequired(MappingContext mappingContext *

Example 2: * * Given GraphQL schema: {@code input MyInput { name: String }} * * Given config: {@code useWrapperForNullableInputTypes = true} - * * Return: {@code GraphQLInputParameter} + * * Return: {@code ArgumentValue} * *

Example 2: * * Given GraphQL schema: {@code input MyInput { name: String[] }} @@ -134,35 +134,35 @@ public abstract String wrapApiReturnTypeIfRequired(MappingContext mappingContext * @param mappingContext Global mapping context * @param namedDefinition Named definition * @param parentTypeName Name of the parent type - * @return Java type wrapped into GraphQLInputParameter + * @return Java type wrapped into ArgumentValue */ public abstract String wrapApiInputTypeIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, String parentTypeName); /** - * Wraps type into GraphQLInputParameter, if required. + * Wraps type into ArgumentValue, if required. * *

Example 1: * * Given GraphQL schema: {@code input MyInput { name: String }} * * Given config: {@code useWrapperForNullableInputTypes = true} - * * Return: {@code GraphQLInputParameter.undefined()} + * * Return: {@code ArgumentValue.omitted()} * *

Example 2: * * Given GraphQL schema: {@code input MyInput { name: String = null }} * * Given config: {@code useWrapperForNullableInputTypes = true} - * * Return: {@code GraphQLInputParameter.withNull()} + * * Return: {@code ArgumentValue.ofNullable(null)} * *

Example 2: * * Given GraphQL schema: {@code input MyInput { name: String = "some value" }} * * Given config: {@code useWrapperForNullableInputTypes = true} - * * Return: {@code GraphQLInputParameter.withValue("some value")} + * * Return: {@code ArgumentValue.ofNullable("some value")} * * @param mappingContext Global mapping context * @param namedDefinition Named definition * @param inputValueDefinition Input value definition * @param defaultValue Default value * @param parentTypeName Name of the parent type - * @return Java type wrapped into GraphQLInputParameter + * @return Java type wrapped into ArgumentValue */ public abstract String wrapApiDefaultValueIfRequired(MappingContext mappingContext, NamedDefinition namedDefinition, InputValueDefinition inputValueDefinition, String defaultValue, @@ -238,7 +238,7 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, Type gr NamedDefinition mappedCollectionType = getLanguageType(mappingContext, ((ListType) graphqlType).getType(), name, parentTypeName, false, true); if (mappedCollectionType.isInterfaceOrUnion() && - isInterfaceOrUnion(mappingContext, parentTypeName)) { + isInterfaceOrUnion(mappingContext, parentTypeName)) { mappedCollectionType.setJavaName( wrapSuperTypeIntoList(mappingContext, mappedCollectionType.getJavaName(), mandatory)); } else { @@ -282,7 +282,7 @@ public NamedDefinition getLanguageType(MappingContext mappingContext, String gra } boolean serializeUsingObjectMapper = serializeFieldsUsingObjectMapper.contains(graphQLType) || - serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name); + serializeFieldsUsingObjectMapper.contains(parentTypeName + "." + name); return new NamedDefinition(langTypeName, graphQLType, isInterfaceOrUnion(mappingContext, graphQLType), mandatory, primitiveCanBeUsed, serializeUsingObjectMapper); @@ -327,7 +327,7 @@ public String getResponseReturnType(MappingContext mappingContext, protected boolean isInterfaceOrUnion(MappingContext mappingContext, String graphQLType) { return mappingContext.getInterfacesName().contains(graphQLType) || - mappingContext.getUnionsNames().contains(graphQLType); + mappingContext.getUnionsNames().contains(graphQLType); } } 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 d1c4c45b1..e6f0709d2 100644 --- a/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java +++ b/src/main/java/com/kobylynskyi/graphql/codegen/model/GraphQLCodegenConfiguration.java @@ -358,9 +358,9 @@ public interface GraphQLCodegenConfiguration { /** * Specifies whether input types of generated input classes should be wrapped into - * GraphQLInputParameter. + * ArgumentValue. * - * @return true if input types should be wrapped into GraphQLInputParameter + * @return true if input types should be wrapped into ArgumentValue */ Boolean getUseWrapperForNullableInputTypes(); diff --git a/src/main/resources/templates/java-lang/graphql_input_parameter.ftl b/src/main/resources/templates/java-lang/graphql_input_parameter.ftl deleted file mode 100644 index d73f6b1e6..000000000 --- a/src/main/resources/templates/java-lang/graphql_input_parameter.ftl +++ /dev/null @@ -1,111 +0,0 @@ -<#if package?has_content> -package ${package}; - -<#list imports as import> -import ${import}.*; - - - -<#if generatedAnnotation && generatedInfo.getGeneratedType()?has_content> -@${generatedInfo.getGeneratedType()}( -value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", -date = "${generatedInfo.getDateTime()}" -) - -/** - * A wrapper class for GraphQL input parameters that supports values, null, or undefined. - * This class is designed to handle various types using generics. - * - * @param The type of the input parameter. - */ -public class GraphQLInputParameter { - - private T value; - private boolean isDefined; - - /** - * Private constructor to create a GraphQLInputParameter instance with a value and definition status. - * - * @param value The value of the input parameter. - * @param isDefined A boolean flag indicating whether the value is defined. - */ - private GraphQLInputParameter(T value, boolean isDefined) { - this.value = value; - this.isDefined = isDefined; - } - - /** - * Creates a GraphQLInputParameter instance with a specified value. - * - * @param The type of the input parameter. - * @param value The value of the input parameter. - * @return A GraphQLInputParameter instance with the specified value. - */ - public static GraphQLInputParameter withValue(T value) { - return new GraphQLInputParameter<>(value, true); - } - - /** - * Creates a GraphQLInputParameter instance with a null value. - * - * @param The type of the input parameter. - * @return A GraphQLInputParameter instance with a null value. - */ - public static GraphQLInputParameter withNull() { - return new GraphQLInputParameter<>(null, true); - } - - /** - * Creates a GraphQLInputParameter instance representing an undefined value. - * - * @param The type of the input parameter. - * @return A GraphQLInputParameter instance representing an undefined value. - */ - public static GraphQLInputParameter undefined() { - return new GraphQLInputParameter<>(null, false); - } - - /** - * Checks whether the input parameter has a defined value. - * - * @return {@code true} if the value is defined, {@code false} otherwise. - */ - public boolean isDefined() { - return isDefined; - } - - /** - * Checks whether the input parameter does not have a defined value. - * - * @return {@code false} if the value is defined, {@code true} otherwise. - */ - public boolean isUndefined() { - return !isDefined; - } - - /** - * Gets the value of the input parameter. Throws an IllegalStateException if the value is undefined. - * - * @return The value of the input parameter. - * @throws IllegalStateException If the value is undefined. - */ - public T getValue() { - if (!isDefined) { - throw new IllegalStateException("Value is undefined"); - } - return value; - } - - /** - * Gets the value of the input parameter or default value. - * @param The type of the input parameter. - * @param defaultValue The value to return if the input parameter is undefined. - * @return The value of the input parameter, or a default value if undefined. - */ - public T getValueOrDefault(T defaultValue) { - if (!isDefined) { - return defaultValue; - } - return value; - } -} \ No newline at end of file diff --git a/src/main/resources/templates/kotlin-lang/graphql_input_parameter.ftl b/src/main/resources/templates/kotlin-lang/graphql_input_parameter.ftl deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/resources/templates/scala-lang/graphql_input_parameter.ftl b/src/main/resources/templates/scala-lang/graphql_input_parameter.ftl deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java index 795f94c58..96c808da3 100644 --- a/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java +++ b/src/test/java/com/kobylynskyi/graphql/codegen/GraphQLCodegenInputWrapperTest.java @@ -44,7 +44,6 @@ void generate_CheckFiles() throws Exception { File[] files = Objects.requireNonNull(outputJavaClassesDir.listFiles()); List generatedFileNames = Arrays.stream(files).map(File::getName).sorted().collect(toList()); assertEquals(asList( - "GraphQLInputParameter.java", "InputWithDefaults.java", "MyEnum.java", "SomeObject.java" diff --git a/src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt b/src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt deleted file mode 100644 index 1446f7972..000000000 --- a/src/test/resources/expected-classes/input-wrapper/GraphQLInputParameter.java.txt +++ /dev/null @@ -1,103 +0,0 @@ - - -@javax.annotation.Generated( -value = "com.kobylynskyi.graphql.codegen.GraphQLCodegen", -date = "2020-12-31T23:59:59-0500" -) -/** - * A wrapper class for GraphQL input parameters that supports values, null, or undefined. - * This class is designed to handle various types using generics. - * - * @param The type of the input parameter. - */ -public class GraphQLInputParameter { - - private T value; - private boolean isDefined; - - /** - * Private constructor to create a GraphQLInputParameter instance with a value and definition status. - * - * @param value The value of the input parameter. - * @param isDefined A boolean flag indicating whether the value is defined. - */ - private GraphQLInputParameter(T value, boolean isDefined) { - this.value = value; - this.isDefined = isDefined; - } - - /** - * Creates a GraphQLInputParameter instance with a specified value. - * - * @param The type of the input parameter. - * @param value The value of the input parameter. - * @return A GraphQLInputParameter instance with the specified value. - */ - public static GraphQLInputParameter withValue(T value) { - return new GraphQLInputParameter<>(value, true); - } - - /** - * Creates a GraphQLInputParameter instance with a null value. - * - * @param The type of the input parameter. - * @return A GraphQLInputParameter instance with a null value. - */ - public static GraphQLInputParameter withNull() { - return new GraphQLInputParameter<>(null, true); - } - - /** - * Creates a GraphQLInputParameter instance representing an undefined value. - * - * @param The type of the input parameter. - * @return A GraphQLInputParameter instance representing an undefined value. - */ - public static GraphQLInputParameter undefined() { - return new GraphQLInputParameter<>(null, false); - } - - /** - * Checks whether the input parameter has a defined value. - * - * @return {@code true} if the value is defined, {@code false} otherwise. - */ - public boolean isDefined() { - return isDefined; - } - - /** - * Checks whether the input parameter does not have a defined value. - * - * @return {@code false} if the value is defined, {@code true} otherwise. - */ - public boolean isUndefined() { - return !isDefined; - } - - /** - * Gets the value of the input parameter. Throws an IllegalStateException if the value is undefined. - * - * @return The value of the input parameter. - * @throws IllegalStateException If the value is undefined. - */ - public T getValue() { - if (!isDefined) { - throw new IllegalStateException("Value is undefined"); - } - return value; - } - - /** - * Gets the value of the input parameter or default value. - * @param The type of the input parameter. - * @param defaultValue The value to return if the input parameter is undefined. - * @return The value of the input parameter, or a default value if undefined. - */ - public T getValueOrDefault(T defaultValue) { - if (!isDefined) { - return defaultValue; - } - return value; - } -} \ No newline at end of file diff --git a/src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt b/src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt index 8b88891e3..f55633e44 100644 --- a/src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt +++ b/src/test/resources/expected-classes/input-wrapper/InputWithDefaults.java.txt @@ -10,15 +10,15 @@ public class InputWithDefaults implements java.io.Serializable { private static final long serialVersionUID = 1L; - private GraphQLInputParameter floatVal = GraphQLInputParameter.withValue(1.23); - private GraphQLInputParameter booleanVal = GraphQLInputParameter.withValue(false); - private GraphQLInputParameter intVal = GraphQLInputParameter.withValue(42); - private GraphQLInputParameter stringVal = GraphQLInputParameter.withValue("my-default"); - private GraphQLInputParameter enumVal = GraphQLInputParameter.withValue(MyEnum.ONE); + private org.springframework.graphql.data.ArgumentValue floatVal = org.springframework.graphql.data.ArgumentValue.ofNullable(1.23); + private org.springframework.graphql.data.ArgumentValue booleanVal = org.springframework.graphql.data.ArgumentValue.ofNullable(false); + private org.springframework.graphql.data.ArgumentValue intVal = org.springframework.graphql.data.ArgumentValue.ofNullable(42); + private org.springframework.graphql.data.ArgumentValue stringVal = org.springframework.graphql.data.ArgumentValue.ofNullable("my-default"); + private org.springframework.graphql.data.ArgumentValue enumVal = org.springframework.graphql.data.ArgumentValue.ofNullable(MyEnum.ONE); @javax.validation.constraints.NotNull private MyEnum nonNullEnumVal = MyEnum.TWO; - private GraphQLInputParameter objectWithNullDefault = GraphQLInputParameter.withNull(); - private GraphQLInputParameter objectWithNonNullDefault = GraphQLInputParameter.undefined(); + private org.springframework.graphql.data.ArgumentValue objectWithNullDefault = org.springframework.graphql.data.ArgumentValue.ofNullable(null); + private org.springframework.graphql.data.ArgumentValue objectWithNonNullDefault = org.springframework.graphql.data.ArgumentValue.omitted(); private java.util.List intList = java.util.Arrays.asList(1, 2, 3); private java.util.List intListEmptyDefault = java.util.Collections.emptyList(); @javax.validation.constraints.NotNull @@ -27,7 +27,7 @@ public class InputWithDefaults implements java.io.Serializable { public InputWithDefaults() { } - public InputWithDefaults(GraphQLInputParameter floatVal, GraphQLInputParameter booleanVal, GraphQLInputParameter intVal, GraphQLInputParameter stringVal, GraphQLInputParameter enumVal, MyEnum nonNullEnumVal, GraphQLInputParameter objectWithNullDefault, GraphQLInputParameter objectWithNonNullDefault, java.util.List intList, java.util.List intListEmptyDefault, java.util.List objectListEmptyDefault) { + public InputWithDefaults(org.springframework.graphql.data.ArgumentValue floatVal, org.springframework.graphql.data.ArgumentValue booleanVal, org.springframework.graphql.data.ArgumentValue intVal, org.springframework.graphql.data.ArgumentValue stringVal, org.springframework.graphql.data.ArgumentValue enumVal, MyEnum nonNullEnumVal, org.springframework.graphql.data.ArgumentValue objectWithNullDefault, org.springframework.graphql.data.ArgumentValue objectWithNonNullDefault, java.util.List intList, java.util.List intListEmptyDefault, java.util.List objectListEmptyDefault) { this.floatVal = floatVal; this.booleanVal = booleanVal; this.intVal = intVal; @@ -41,38 +41,38 @@ public class InputWithDefaults implements java.io.Serializable { this.objectListEmptyDefault = objectListEmptyDefault; } - public GraphQLInputParameter getFloatVal() { + public org.springframework.graphql.data.ArgumentValue getFloatVal() { return floatVal; } - public void setFloatVal(GraphQLInputParameter floatVal) { + public void setFloatVal(org.springframework.graphql.data.ArgumentValue floatVal) { this.floatVal = floatVal; } - public GraphQLInputParameter getBooleanVal() { + public org.springframework.graphql.data.ArgumentValue getBooleanVal() { return booleanVal; } - public void setBooleanVal(GraphQLInputParameter booleanVal) { + public void setBooleanVal(org.springframework.graphql.data.ArgumentValue booleanVal) { this.booleanVal = booleanVal; } - public GraphQLInputParameter getIntVal() { + public org.springframework.graphql.data.ArgumentValue getIntVal() { return intVal; } - public void setIntVal(GraphQLInputParameter intVal) { + public void setIntVal(org.springframework.graphql.data.ArgumentValue intVal) { this.intVal = intVal; } - public GraphQLInputParameter getStringVal() { + public org.springframework.graphql.data.ArgumentValue getStringVal() { return stringVal; } - public void setStringVal(GraphQLInputParameter stringVal) { + public void setStringVal(org.springframework.graphql.data.ArgumentValue stringVal) { this.stringVal = stringVal; } - public GraphQLInputParameter getEnumVal() { + public org.springframework.graphql.data.ArgumentValue getEnumVal() { return enumVal; } - public void setEnumVal(GraphQLInputParameter enumVal) { + public void setEnumVal(org.springframework.graphql.data.ArgumentValue enumVal) { this.enumVal = enumVal; } @@ -83,17 +83,17 @@ public class InputWithDefaults implements java.io.Serializable { this.nonNullEnumVal = nonNullEnumVal; } - public GraphQLInputParameter getObjectWithNullDefault() { + public org.springframework.graphql.data.ArgumentValue getObjectWithNullDefault() { return objectWithNullDefault; } - public void setObjectWithNullDefault(GraphQLInputParameter objectWithNullDefault) { + public void setObjectWithNullDefault(org.springframework.graphql.data.ArgumentValue objectWithNullDefault) { this.objectWithNullDefault = objectWithNullDefault; } - public GraphQLInputParameter getObjectWithNonNullDefault() { + public org.springframework.graphql.data.ArgumentValue getObjectWithNonNullDefault() { return objectWithNonNullDefault; } - public void setObjectWithNonNullDefault(GraphQLInputParameter objectWithNonNullDefault) { + public void setObjectWithNonNullDefault(org.springframework.graphql.data.ArgumentValue objectWithNonNullDefault) { this.objectWithNonNullDefault = objectWithNonNullDefault; } @@ -130,14 +130,14 @@ public class InputWithDefaults implements java.io.Serializable { ) public static class Builder { - private GraphQLInputParameter floatVal = GraphQLInputParameter.withValue(1.23); - private GraphQLInputParameter booleanVal = GraphQLInputParameter.withValue(false); - private GraphQLInputParameter intVal = GraphQLInputParameter.withValue(42); - private GraphQLInputParameter stringVal = GraphQLInputParameter.withValue("my-default"); - private GraphQLInputParameter enumVal = GraphQLInputParameter.withValue(MyEnum.ONE); + private org.springframework.graphql.data.ArgumentValue floatVal = org.springframework.graphql.data.ArgumentValue.ofNullable(1.23); + private org.springframework.graphql.data.ArgumentValue booleanVal = org.springframework.graphql.data.ArgumentValue.ofNullable(false); + private org.springframework.graphql.data.ArgumentValue intVal = org.springframework.graphql.data.ArgumentValue.ofNullable(42); + private org.springframework.graphql.data.ArgumentValue stringVal = org.springframework.graphql.data.ArgumentValue.ofNullable("my-default"); + private org.springframework.graphql.data.ArgumentValue enumVal = org.springframework.graphql.data.ArgumentValue.ofNullable(MyEnum.ONE); private MyEnum nonNullEnumVal = MyEnum.TWO; - private GraphQLInputParameter objectWithNullDefault = GraphQLInputParameter.withNull(); - private GraphQLInputParameter objectWithNonNullDefault = GraphQLInputParameter.undefined(); + private org.springframework.graphql.data.ArgumentValue objectWithNullDefault = org.springframework.graphql.data.ArgumentValue.ofNullable(null); + private org.springframework.graphql.data.ArgumentValue objectWithNonNullDefault = org.springframework.graphql.data.ArgumentValue.omitted(); private java.util.List intList = java.util.Arrays.asList(1, 2, 3); private java.util.List intListEmptyDefault = java.util.Collections.emptyList(); private java.util.List objectListEmptyDefault = java.util.Collections.emptyList(); @@ -145,27 +145,27 @@ public class InputWithDefaults implements java.io.Serializable { public Builder() { } - public Builder setFloatVal(GraphQLInputParameter floatVal) { + public Builder setFloatVal(org.springframework.graphql.data.ArgumentValue floatVal) { this.floatVal = floatVal; return this; } - public Builder setBooleanVal(GraphQLInputParameter booleanVal) { + public Builder setBooleanVal(org.springframework.graphql.data.ArgumentValue booleanVal) { this.booleanVal = booleanVal; return this; } - public Builder setIntVal(GraphQLInputParameter intVal) { + public Builder setIntVal(org.springframework.graphql.data.ArgumentValue intVal) { this.intVal = intVal; return this; } - public Builder setStringVal(GraphQLInputParameter stringVal) { + public Builder setStringVal(org.springframework.graphql.data.ArgumentValue stringVal) { this.stringVal = stringVal; return this; } - public Builder setEnumVal(GraphQLInputParameter enumVal) { + public Builder setEnumVal(org.springframework.graphql.data.ArgumentValue enumVal) { this.enumVal = enumVal; return this; } @@ -175,12 +175,12 @@ public class InputWithDefaults implements java.io.Serializable { return this; } - public Builder setObjectWithNullDefault(GraphQLInputParameter objectWithNullDefault) { + public Builder setObjectWithNullDefault(org.springframework.graphql.data.ArgumentValue objectWithNullDefault) { this.objectWithNullDefault = objectWithNullDefault; return this; } - public Builder setObjectWithNonNullDefault(GraphQLInputParameter objectWithNonNullDefault) { + public Builder setObjectWithNonNullDefault(org.springframework.graphql.data.ArgumentValue objectWithNonNullDefault) { this.objectWithNonNullDefault = objectWithNonNullDefault; return this; } diff --git a/src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt b/src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt index a96fbbff6..c82cb4b6c 100644 --- a/src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt +++ b/src/test/resources/expected-classes/input-wrapper/SomeObject.java.txt @@ -9,12 +9,12 @@ public class SomeObject implements java.io.Serializable { @javax.validation.constraints.NotNull private String name; - private GraphQLInputParameter description = GraphQLInputParameter.undefined(); + private org.springframework.graphql.data.ArgumentValue description = org.springframework.graphql.data.ArgumentValue.omitted(); public SomeObject() { } - public SomeObject(String name, GraphQLInputParameter description) { + public SomeObject(String name, org.springframework.graphql.data.ArgumentValue description) { this.name = name; this.description = description; } @@ -26,10 +26,10 @@ public class SomeObject implements java.io.Serializable { this.name = name; } - public GraphQLInputParameter getDescription() { + public org.springframework.graphql.data.ArgumentValue getDescription() { return description; } - public void setDescription(GraphQLInputParameter description) { + public void setDescription(org.springframework.graphql.data.ArgumentValue description) { this.description = description; } @@ -46,7 +46,7 @@ public class SomeObject implements java.io.Serializable { public static class Builder { private String name; - private GraphQLInputParameter description = GraphQLInputParameter.undefined(); + private org.springframework.graphql.data.ArgumentValue description = org.springframework.graphql.data.ArgumentValue.omitted(); public Builder() { } @@ -56,7 +56,7 @@ public class SomeObject implements java.io.Serializable { return this; } - public Builder setDescription(GraphQLInputParameter description) { + public Builder setDescription(org.springframework.graphql.data.ArgumentValue description) { this.description = description; return this; } From 4c239fcdf6778d8b239d45fcff9275d3942b1be6 Mon Sep 17 00:00:00 2001 From: Roland Wolf Date: Wed, 17 Jan 2024 17:39:53 +0100 Subject: [PATCH 17/18] update link in description --- docs/codegen-options.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/codegen-options.md b/docs/codegen-options.md index 33724f565..2efd0942a 100644 --- a/docs/codegen-options.md +++ b/docs/codegen-options.md @@ -44,7 +44,7 @@ | `generateExtensionFieldsResolvers` | Boolean | False | Specifies whether all fields in extensions (`extend type` and `extend interface`) should be present in Resolver interface instead of the type class itself. | | `generateModelsForRootTypes` | Boolean | False | Specifies whether model classes should be generated for `type Query`, `type Subscription`, `type Mutation`. | | `useOptionalForNullableReturnTypes` | Boolean | False | Specifies whether nullable return types of api methods should be wrapped into [`java.util.Optional<>`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Optional.html). Lists will not be wrapped. | -| `useWrapperForNullableInputTypes` | Boolean | False | Specifies whether nullable parameters on input types should be wrapped into [`ArgumentValue<>`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Optional.html). This requires org.springframework.graphql.data version 1.1.0+. Lists will not be wrapped. | +| `useWrapperForNullableInputTypes` | Boolean | False | Specifies whether nullable parameters on input types should be wrapped into [`ArgumentValue<>`](https://docs.spring.io/spring-graphql/docs/current/api/org/springframework/graphql/data/ArgumentValue.html). This requires org.springframework.graphql.data version 1.1.0+. Lists will not be wrapped. | | `generateApisWithThrowsException` | Boolean | True | Specifies whether api interface methods should have `throws Exception` in signature. | | `generateApisWithSuspendFunctions` | Boolean | False | Specifies whether api interface methods should have `suspend` modifier in signature. Only supported in Kotlin. | | `generateNoArgsConstructorOnly` | Boolean | False | Specifies whether model classes should only have a no-args constructor. All-args constructor will not be generated in case value is true | @@ -70,8 +70,7 @@ | `supportUnknownFields` | Boolean | False | Specifies whether api classes should support unknown fields during serialization or deserialization. If `true`, classes will include a property of type [`java.util.Map`](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Map.html) that will store unknown fields. | | `unknownFieldsPropertyName` | String | userDefinedFields | Specifies the name of the property to be included in api classes to support unknown fields during serialization or deserialization | | `skip` | Boolean | False | If true, then code generation will not happen | -| `skipSchemaSizeLimit` | Boolean | True | When set to true, the GraphQL schema will be processed with token, character, line and rule depth limits. Set to false to process the schema regardless of its size. -| +| `skipSchemaSizeLimit` | Boolean | True | When set to true, the GraphQL schema will be processed with token, character, line and rule depth limits. Set to false to process the schema regardless of its size. | ### Option `graphqlSchemas` From 886bd2948868e98cd2450d6abf42af55b73b1986 Mon Sep 17 00:00:00 2001 From: Bogdan Kobylynskyi <92bogdan@gmail.com> Date: Thu, 1 Feb 2024 16:45:56 -0500 Subject: [PATCH 18/18] Delete .java-version --- .java-version | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .java-version diff --git a/.java-version b/.java-version deleted file mode 100644 index 625934097..000000000 --- a/.java-version +++ /dev/null @@ -1 +0,0 @@ -1.8