Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[java-micronaut] Support Optional for non-required properties #12144

Merged
merged 1 commit into from
Apr 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/generators/java-micronaut-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|testOutput|Set output folder for models and APIs tests| |${project.build.directory}/generated-test-sources/openapi|
|title|Client service name| |null|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useOptional|Use Optional container for optional parameters| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

## SUPPORTED VENDOR EXTENSIONS
Expand Down
1 change: 1 addition & 0 deletions docs/generators/java-micronaut-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|title|Client service name| |null|
|useAuth|Whether to import authorization and to annotate controller methods accordingly| |true|
|useBeanValidation|Use BeanValidation API annotations| |true|
|useOptional|Use Optional container for optional parameters| |false|
|withXml|whether to include support for application/xml content type and include XML annotations in the model (works with libraries that provide support for JSON and XML)| |false|

## SUPPORTED VENDOR EXTENSIONS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.*;
import org.openapitools.codegen.languages.features.BeanValidationFeatures;
import org.openapitools.codegen.languages.features.OptionalFeatures;
import org.openapitools.codegen.meta.features.DocumentationFeature;
import org.openapitools.codegen.meta.features.SecurityFeature;
import org.openapitools.codegen.model.ModelMap;
Expand All @@ -15,7 +16,7 @@

import static org.openapitools.codegen.CodegenConstants.INVOKER_PACKAGE;

public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen implements BeanValidationFeatures {
public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen implements BeanValidationFeatures, OptionalFeatures {
public static final String OPT_TITLE = "title";
public static final String OPT_BUILD = "build";
public static final String OPT_BUILD_GRADLE = "gradle";
Expand All @@ -34,6 +35,7 @@ public abstract class JavaMicronautAbstractCodegen extends AbstractJavaCodegen i

protected String title;
protected boolean useBeanValidation;
protected boolean useOptional;
protected String buildTool;
protected String testTool;
protected boolean requiredPropertiesInConstructor = true;
Expand All @@ -52,6 +54,7 @@ public JavaMicronautAbstractCodegen() {

// Set all the fields
useBeanValidation = true;
useOptional = false;
buildTool = OPT_BUILD_ALL;
testTool = OPT_TEST_JUNIT;
outputFolder = "generated-code/java-micronaut-client";
Expand Down Expand Up @@ -95,6 +98,7 @@ public JavaMicronautAbstractCodegen() {
cliOptions.add(new CliOption(OPT_TITLE, "Client service name").defaultValue(title));
cliOptions.add(new CliOption(OPT_MICRONAUT_VERSION, "Micronaut version, only >=3.0.0 versions are supported").defaultValue(micronautVersion));
cliOptions.add(CliOption.newBoolean(USE_BEANVALIDATION, "Use BeanValidation API annotations", useBeanValidation));
cliOptions.add(CliOption.newBoolean(USE_OPTIONAL, "Use Optional container for optional parameters", useOptional));
cliOptions.add(CliOption.newBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR, "Allow only to create models with all the required properties provided in constructor", requiredPropertiesInConstructor));

CliOption buildToolOption = new CliOption(OPT_BUILD, "Specify for which build tool to generate files").defaultValue(buildTool);
Expand Down Expand Up @@ -158,6 +162,11 @@ public void processOpts() {
}
writePropertyBack(USE_BEANVALIDATION, useBeanValidation);

if (additionalProperties.containsKey(USE_OPTIONAL)) {
this.setUseOptional(convertPropertyToBoolean(USE_OPTIONAL));
}
writePropertyBack(USE_OPTIONAL, useOptional);

if (additionalProperties.containsKey(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR)) {
this.requiredPropertiesInConstructor = convertPropertyToBoolean(OPT_REQUIRED_PROPERTIES_IN_CONSTRUCTOR);
}
Expand Down Expand Up @@ -306,6 +315,11 @@ public void setUseBeanValidation(boolean useBeanValidation) {
this.useBeanValidation = useBeanValidation;
}

@Override
public void setUseOptional(boolean useOptional) {
this.useOptional = useOptional;
}

@Override
public String toApiVarName(String name) {
String apiVarName = super.toApiVarName(name);
Expand All @@ -319,6 +333,10 @@ public boolean isUseBeanValidation() {
return useBeanValidation;
}

public boolean isUseOptional() {
return useOptional;
}

@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
objs = super.postProcessOperationsWithModels(objs, allModels);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ validate all pojos and enums
nullable & nonnull
}}{{#required}}{{#isNullable}} @Nullable
{{/isNullable}}{{^isNullable}} @NotNull
{{/isNullable}}{{/required}}{{^required}} @Nullable
{{/required}}{{!
{{/isNullable}}{{/required}}{{^required}}{{^useOptional}} @Nullable
{{/useOptional}}{{/required}}{{!
pattern
}}{{#pattern}}{{^isByteArray}} @Pattern(regexp="{{{pattern}}}")
{{/isByteArray}}{{/pattern}}{{!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
{{/useReflectionEqualsHashCode}}
import java.util.Objects;
import java.util.Arrays;
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{#imports}}
import {{import}};
{{/imports}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ Declare the class with extends and implements
{{/vendorExtensions.x-is-jackson-optional-nullable}}
{{^vendorExtensions.x-is-jackson-optional-nullable}}
{{#jackson}}
{{>common/model/jackson_annotations}}{{/jackson}}{{/vendorExtensions.x-is-jackson-optional-nullable}} public {{{datatypeWithEnum}}} {{getter}}() {
{{>common/model/jackson_annotations}}{{/jackson}}{{/vendorExtensions.x-is-jackson-optional-nullable}} public {{#useOptional}}{{^required}}Optional<{{/required}}{{/useOptional}}{{{datatypeWithEnum}}}{{#useOptional}}{{^required}}>{{/required}}{{/useOptional}} {{getter}}() {
{{#vendorExtensions.x-is-jackson-optional-nullable}}
{{#isReadOnly}}
{{! A readonly attribute doesn't have setter => jackson will set null directly if explicitly returned by API, so make sure we have an empty JsonNullable}} if ({{name}} == null) {
Expand All @@ -196,7 +196,17 @@ Declare the class with extends and implements
return {{name}}.orElse(null);
{{/vendorExtensions.x-is-jackson-optional-nullable}}
{{^vendorExtensions.x-is-jackson-optional-nullable}}
{{#useOptional}}
{{#required}}
return {{name}};
{{/required}}
{{^required}}
return Optional.ofNullable({{name}});
{{/required}}
{{/useOptional}}
{{^useOptional}}
return {{name}};
{{/useOptional}}
{{/vendorExtensions.x-is-jackson-optional-nullable}}
}
Expand Down