openapi-generator
openapi-generator copied to clipboard
[BUG] [ALL] inconsistent handling of boolean additionalProperties [JAVA] additionalProperties.put("useOptional", "false") means true in mustache template
- [x] Have you provided a full/minimal spec to reproduce the issue?
- [ ] Have you validated the input using an OpenAPI validator (example)?
- [x] Have you tested with the latest master to confirm the issue still exists?
- [x] Have you searched for related issues/PRs?
- [ ] What's the actual output vs expected output?
- [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
xxxCodegen.processOpt() uses several techniques to process boolean additionalProperties:
if (additionalProperties.containsKey(CodegenConstants.SORT_MODEL_PROPERTIES_BY_REQUIRED_FLAG)) {
this.setSortModelPropertiesByRequiredFlag(Boolean.valueOf(additionalProperties
.get(CodegenConstants.SORT_MODEL_PROPERTIES_BY_REQUIRED_FLAG).toString()));
}
}
if (additionalProperties.containsKey(USE_RUNTIME_EXCEPTION)) {
this.setUseRuntimeException(convertPropertyToBooleanAndWriteBack(USE_RUNTIME_EXCEPTION));
}
if (additionalProperties.containsKey(SPRING_CONTROLLER)) {
this.setUseSpringController(convertPropertyToBoolean(SPRING_CONTROLLER));
}
writePropertyBack(SPRING_CONTROLLER, useSpringController);
if (additionalProperties.containsKey(USE_OPTIONAL)) {
this.setUseOptional(convertPropertyToBoolean(USE_OPTIONAL));
}
if (useOptional) {
writePropertyBack(USE_OPTIONAL, useOptional);
}
Each one have slightly different behaviour or even nasty side effects.
Let's take useOptional in SpringCodegen:
additionalProperties.put("useOptional", "false")
It gives springCodegen.useOptional = false but in templates useOptional is true
For example:
{{#useOptional}}useOptional:{{useOptional}}{{/useOptional}}
generates useOptional:false
openapi-generator version
all (including 7.6.0)
Generation Details
Steps to reproduce
SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(OPENAPI_NULLABLE, "true");
codegen.additionalProperties().put(USE_OPTIONAL, "false");
...
->
Optional<xxx>
are generated in the models
SpringCodegen codegen = new SpringCodegen();
codegen.additionalProperties().put(OPENAPI_NULLABLE, "true");
codegen.additionalProperties().put(USE_OPTIONAL, false);
...
Optional<xxx>
are not generated in the models
This is because OPENAPI_NULLABLE is written back in additionalProperties:
if (additionalProperties.containsKey(OPENAPI_NULLABLE)) {
this.setOpenApiNullable(Boolean.parseBoolean(additionalProperties.get(OPENAPI_NULLABLE).toString()));
}
additionalProperties.put(OPENAPI_NULLABLE, openApiNullable);
but USE_OPTIONAL is only written back if it is equals to true or "true"
Related issues/PRs
Suggest a fix (from most verbose to least verbose)
- use convertPropertyToBooleanAndWriteBack (or equivalent) everywhere
- use Consumer
in processOpts
processAdditionalProperty(USE_OPTIONAL, SpringCodeGen::setUseOptional);
public void processAdditionalProperty(String propertyKey, Consumer<Boolean> consumer) {
if (additionalProperties.contains(propertyKey)) {
boolean value = convertPropertyToBoolean(propertyKey);
consumer.accept(value);
writePropertyBack(propertyKey, value);
}
}
- use Consumer
in cliOptions.add(CliOption.newBoolean(...))
cliOptions.add(
CliOption.newBoolean(USE_OPTIONAL, // property name
"Use Optional container for optional parameters", // description
useOptional, // default value
SpringCodeGen::setUseOptional)); // setter when additionalProperty is set
and loop into all boolean cliOptions. Call processAdditionalProperty()
I think the last 2 options are the best. I can create a PR with the prefered option