diff --git a/bin/configs/java-okhttp-gson.yaml b/bin/configs/java-okhttp-gson.yaml index a93c8263ddb..d3def489a5c 100644 --- a/bin/configs/java-okhttp-gson.yaml +++ b/bin/configs/java-okhttp-gson.yaml @@ -14,3 +14,6 @@ additionalProperties: hideGenerationTimestamp: "true" useOneOfDiscriminatorLookup: "true" disallowAdditionalPropertiesIfNotPresent: false +enumNameMappings: + s: LOWER_CASE_S + S: UPPER_CASE_S diff --git a/docs/customization.md b/docs/customization.md index e256c8b9b36..5833650b98f 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -421,7 +421,13 @@ java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generat ``` will rename the `Tag` schema to `Label` instead. -Not all generators support thess features yet. Please give it a try to confirm the behaviour and open an issue (ticket) to let us know which generators you would like to have this feature enabled and we'll prioritize accordingly. We also welcome PRs to add these features to generators. Related PRs for reference: #16209, #16234 (modelNameMappings), #16194, #16206 (nameMappings, parameterNameMappings). +To map enum names, use `enumNameMappings` option, e.g. +```sh +java -jar modules/openapi-generator-cli/target/openapi-generator-cli.jar generate -g java -i modules/openapi-generator/src/test/resources/3_0/petstore.yaml -o /tmp/java/ --enum-name-mappings sold=UNAVAILABLE +``` +will rename SOLD to UNAVAILABLE instead. + +Not all generators support thess features yet. Please give it a try to confirm the behaviour and open an issue (ticket) to let us know which generators you would like to have this feature enabled and we'll prioritize accordingly. We also welcome PRs to add these features to generators. Related PRs for reference: #16209, #16234 (modelNameMappings), #16194, #16206 (nameMappings, parameterNameMappings), #17108 (enumNameMappings). NOTE: some generators use `baseName` (original name obtained direclty from OpenAPI spec, e.g. `shipping-date`) mustache tag in the templates so the mapping feature won't work. diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java index fd379374fba..15ae470ea30 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/ConfigHelp.java @@ -89,6 +89,9 @@ public class ConfigHelp extends OpenApiGeneratorCommand { @Option(name = {"--model-name-mappings"}, title = "model name mappings", description = "displays the model name mappings (none)") private Boolean modelNameMappings; + @Option(name = {"--enum-name-mappings"}, title = "enum name mappings", description = "displays the enum name mappings (none)") + private Boolean enumNameMappings; + @Option(name = {"--openapi-normalizer"}, title = "openapi normalizer rules", description = "displays the OpenAPI normalizer rules (none)") private Boolean openapiNormalizer; @@ -542,6 +545,18 @@ public class ConfigHelp extends OpenApiGeneratorCommand { sb.append(newline); } + if (Boolean.TRUE.equals(enumNameMappings)) { + sb.append(newline).append("ENUM NAME MAPPING").append(newline).append(newline); + Map map = config.enumNameMapping() + .entrySet() + .stream() + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> { + throw new IllegalStateException(String.format(Locale.ROOT, "Duplicated options! %s and %s", a, b)); + }, TreeMap::new)); + writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "enum name", "Mapped to"); + sb.append(newline); + } + if (Boolean.TRUE.equals(openapiNormalizer)) { sb.append(newline).append("OPENAPI NORMALIZER RULES").append(newline).append(newline); Map map = config.openapiNormalizer() diff --git a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java index 7d4ed09e27b..14c251133fe 100644 --- a/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java +++ b/modules/openapi-generator-cli/src/main/java/org/openapitools/codegen/cmd/Generate.java @@ -209,6 +209,13 @@ public class Generate extends OpenApiGeneratorCommand { + " You can also have multiple occurrences of this option.") private List modelNameMappings = new ArrayList<>(); + @Option( + name = {"--enum-name-mappings"}, + title = "enum name mappings", + description = "specifies mappings between the enum name and the new name in the format of enum_name=AnotherName,enum_name2=OtherName2." + + " You can also have multiple occurrences of this option.") + private List enumNameMappings = new ArrayList<>(); + @Option( name = {"--openapi-normalizer"}, title = "OpenAPI normalizer rules", @@ -492,6 +499,7 @@ public class Generate extends OpenApiGeneratorCommand { applyNameMappingsKvpList(nameMappings, configurator); applyParameterNameMappingsKvpList(parameterNameMappings, configurator); applyModelNameMappingsKvpList(modelNameMappings, configurator); + applyEnumNameMappingsKvpList(enumNameMappings, configurator); applyOpenAPINormalizerKvpList(openapiNormalizer, configurator); applyTypeMappingsKvpList(typeMappings, configurator); applyAdditionalPropertiesKvpList(additionalProperties, configurator); diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java index 2af439c4dae..8be7441ff03 100644 --- a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/config/GeneratorSettings.java @@ -56,6 +56,7 @@ public final class GeneratorSettings implements Serializable { private final Map nameMappings; private final Map parameterNameMappings; private final Map modelNameMappings; + private final Map enumNameMappings; private final Map openapiNormalizer; private final Set languageSpecificPrimitives; private final Map reservedWordsMappings; @@ -295,6 +296,15 @@ public final class GeneratorSettings implements Serializable { return modelNameMappings; } + /** + * Gets enum name mappings between an enum name and the new name. + * + * @return the enum name mappings + */ + public Map getEnumNameMappings() { + return enumNameMappings; + } + /** * Gets OpenAPI normalizer rules * @@ -425,6 +435,7 @@ public final class GeneratorSettings implements Serializable { nameMappings = Collections.unmodifiableMap(builder.nameMappings); parameterNameMappings = Collections.unmodifiableMap(builder.parameterNameMappings); modelNameMappings = Collections.unmodifiableMap(builder.modelNameMappings); + enumNameMappings = Collections.unmodifiableMap(builder.enumNameMappings); openapiNormalizer = Collections.unmodifiableMap(builder.openapiNormalizer); languageSpecificPrimitives = Collections.unmodifiableSet(builder.languageSpecificPrimitives); reservedWordsMappings = Collections.unmodifiableMap(builder.reservedWordsMappings); @@ -502,6 +513,7 @@ public final class GeneratorSettings implements Serializable { nameMappings = Collections.unmodifiableMap(new HashMap<>(0)); parameterNameMappings = Collections.unmodifiableMap(new HashMap<>(0)); modelNameMappings = Collections.unmodifiableMap(new HashMap<>(0)); + enumNameMappings = Collections.unmodifiableMap(new HashMap<>(0)); openapiNormalizer = Collections.unmodifiableMap(new HashMap<>(0)); languageSpecificPrimitives = Collections.unmodifiableSet(new HashSet<>(0)); reservedWordsMappings = Collections.unmodifiableMap(new HashMap<>(0)); @@ -572,6 +584,9 @@ public final class GeneratorSettings implements Serializable { if (copy.getModelNameMappings() != null) { builder.modelNameMappings.putAll(copy.getModelNameMappings()); } + if (copy.getEnumNameMappings() != null) { + builder.enumNameMappings.putAll(copy.getEnumNameMappings()); + } if (copy.getOpenAPINormalizer() != null) { builder.openapiNormalizer.putAll(copy.getOpenAPINormalizer()); } @@ -620,6 +635,7 @@ public final class GeneratorSettings implements Serializable { private Map nameMappings; private Map parameterNameMappings; private Map modelNameMappings; + private Map enumNameMappings; private Map openapiNormalizer; private Set languageSpecificPrimitives; private Map reservedWordsMappings; @@ -644,6 +660,7 @@ public final class GeneratorSettings implements Serializable { nameMappings = new HashMap<>(); parameterNameMappings = new HashMap<>(); modelNameMappings = new HashMap<>(); + enumNameMappings = new HashMap<>(); openapiNormalizer = new HashMap<>(); languageSpecificPrimitives = new HashSet<>(); reservedWordsMappings = new HashMap<>(); @@ -1043,6 +1060,32 @@ public final class GeneratorSettings implements Serializable { return this; } + /** + * Sets the {@code enumNameMappings} and returns a reference to this Builder so that the methods can be chained together. + * + * @param enumNameMappings the {@code enumNameMappings} to set + * @return a reference to this Builder + */ + public Builder withEnumNameMappings(Map enumNameMappings) { + this.enumNameMappings = enumNameMappings; + return this; + } + + /** + * Sets a single {@code enumNameMappings} and returns a reference to this Builder so that the methods can be chained together. + * + * @param key A key for the name mapping + * @param value The value of name mapping + * @return a reference to this Builder + */ + public Builder withEnumNameMapping(String key, String value) { + if (this.enumNameMappings == null) { + this.enumNameMappings = new HashMap<>(); + } + this.enumNameMappings.put(key, value); + return this; + } + /** * Sets the {@code openapiNormalizer} and returns a reference to this Builder so that the methods can be chained together. * @@ -1259,6 +1302,7 @@ public final class GeneratorSettings implements Serializable { Objects.equals(getNameMappings(), that.getNameMappings()) && Objects.equals(getParameterNameMappings(), that.getParameterNameMappings()) && Objects.equals(getModelNameMappings(), that.getModelNameMappings()) && + Objects.equals(getEnumNameMappings(), that.getEnumNameMappings()) && Objects.equals(getOpenAPINormalizer(), that.getOpenAPINormalizer()) && Objects.equals(getLanguageSpecificPrimitives(), that.getLanguageSpecificPrimitives()) && Objects.equals(getReservedWordsMappings(), that.getReservedWordsMappings()) && @@ -1294,6 +1338,7 @@ public final class GeneratorSettings implements Serializable { getNameMappings(), getParameterNameMappings(), getModelNameMappings(), + getEnumNameMappings(), getOpenAPINormalizer(), getLanguageSpecificPrimitives(), getReservedWordsMappings(), diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt index 04e654942b6..50d78ac6ee1 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/extensions/OpenApiGeneratorGenerateExtension.kt @@ -182,6 +182,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) { */ val modelNameMappings = project.objects.mapProperty() + /** + * Specifies mappings between an enum name and the new name + */ + val enumNameMappings = project.objects.mapProperty() + /** * Specifies mappings (rules) in OpenAPI normalizer */ diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt index 3eeb5955a74..b6f90a9aa05 100644 --- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt +++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt @@ -293,6 +293,13 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac @Input val modelNameMappings = project.objects.mapProperty() + /** + * Specifies mappings between the enum name and the new name + */ + @Optional + @Input + val enumNameMappings = project.objects.mapProperty() + /** * Specifies mappings (rules) in OpenAPI normalizer */ @@ -852,6 +859,12 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac } } + if (enumNameMappings.isPresent) { + enumNameMappings.get().forEach { entry -> + configurator.addEnumNameMapping(entry.key, entry.value) + } + } + if (openapiNormalizer.isPresent) { openapiNormalizer.get().forEach { entry -> configurator.addOpenAPINormalizer(entry.key, entry.value) diff --git a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java index 2237a76c315..8a2d021d250 100644 --- a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java +++ b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java @@ -350,6 +350,12 @@ public class CodeGenMojo extends AbstractMojo { @Parameter(name = "modelNameMappings", property = "openapi.generator.maven.plugin.modelNameMappings") private List modelNameMappings; + /** + * A map of enum names and the new names + */ + @Parameter(name = "enumNameMappings", property = "openapi.generator.maven.plugin.enumNameMappings") + private List enumNameMappings; + /** * A set of rules for OpenAPI normalizer */ @@ -834,6 +840,11 @@ public class CodeGenMojo extends AbstractMojo { applyModelNameMappingsKvpList(modelNameMappings, configurator); } + // Apply Enum Name Mappings + if (enumNameMappings != null && (configOptions == null || !configOptions.containsKey("enum-name-mappings"))) { + applyEnumNameMappingsKvpList(enumNameMappings, configurator); + } + // Apply OpenAPI normalizer rules if (openapiNormalizer != null && (configOptions == null || !configOptions.containsKey("openapi-normalizer"))) { applyOpenAPINormalizerKvpList(openapiNormalizer, configurator); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java index 59651d41e40..1fedb4eeead 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfig.java @@ -155,6 +155,8 @@ public interface CodegenConfig { Map modelNameMapping(); + Map enumNameMapping(); + Map openapiNormalizer(); Map apiTemplateFiles(); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 73d39c8bc82..582b58938df 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -173,6 +173,8 @@ public class DefaultCodegen implements CodegenConfig { protected Map parameterNameMapping = new HashMap<>(); // a map to store the mapping between model name and the name provided by the user protected Map modelNameMapping = new HashMap<>(); + // a map to store the mapping between enum name and the name provided by the user + protected Map enumNameMapping = new HashMap<>(); // a map to store the rules in OpenAPI Normalizer protected Map openapiNormalizer = new HashMap<>(); protected String modelPackage = "", apiPackage = "", fileSuffix; @@ -1244,6 +1246,11 @@ public class DefaultCodegen implements CodegenConfig { return modelNameMapping; } + @Override + public Map enumNameMapping() { + return enumNameMapping; + } + @Override public Map openapiNormalizer() { return openapiNormalizer; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java index c81cd523fe3..234efba154f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java @@ -74,6 +74,7 @@ public class CodegenConfigurator { private Map nameMappings = new HashMap<>(); private Map parameterNameMappings = new HashMap<>(); private Map modelNameMappings = new HashMap<>(); + private Map enumNameMappings = new HashMap<>(); private Map openapiNormalizer = new HashMap<>(); private Set languageSpecificPrimitives = new HashSet<>(); private Map reservedWordsMappings = new HashMap<>(); @@ -136,6 +137,9 @@ public class CodegenConfigurator { if(generatorSettings.getModelNameMappings() != null) { configurator.modelNameMappings.putAll(generatorSettings.getModelNameMappings()); } + if(generatorSettings.getEnumNameMappings() != null) { + configurator.enumNameMappings.putAll(generatorSettings.getEnumNameMappings()); + } if(generatorSettings.getOpenAPINormalizer() != null) { configurator.openapiNormalizer.putAll(generatorSettings.getOpenAPINormalizer()); } @@ -244,6 +248,12 @@ public class CodegenConfigurator { return this; } + public CodegenConfigurator addEnumNameMapping(String key, String value) { + this.enumNameMappings.put(key, value); + generatorSettingsBuilder.withEnumNameMapping(key, value); + return this; + } + public CodegenConfigurator addOpenAPINormalizer(String key, String value) { this.openapiNormalizer.put(key, value); generatorSettingsBuilder.withOpenAPINormalizer(key, value); @@ -440,6 +450,12 @@ public class CodegenConfigurator { return this; } + public CodegenConfigurator setEnumNameMappings(Map enumNameMappings) { + this.enumNameMappings = enumNameMappings; + generatorSettingsBuilder.withEnumNameMappings(enumNameMappings); + return this; + } + public CodegenConfigurator setOpenAPINormalizer(Map openapiNormalizer) { this.openapiNormalizer = openapiNormalizer; generatorSettingsBuilder.withOpenAPINormalizer(openapiNormalizer); @@ -728,6 +744,7 @@ public class CodegenConfigurator { config.nameMapping().putAll(generatorSettings.getNameMappings()); config.parameterNameMapping().putAll(generatorSettings.getParameterNameMappings()); config.modelNameMapping().putAll(generatorSettings.getModelNameMappings()); + config.enumNameMapping().putAll(generatorSettings.getEnumNameMappings()); config.openapiNormalizer().putAll(generatorSettings.getOpenAPINormalizer()); config.languageSpecificPrimitives().addAll(generatorSettings.getLanguageSpecificPrimitives()); config.reservedWordsMappings().putAll(generatorSettings.getReservedWordsMappings()); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java index c6a871b7c42..5b57bde6abf 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfiguratorUtils.java @@ -159,6 +159,19 @@ public final class CodegenConfiguratorUtils { } } + public static void applyEnumNameMappingsKvpList(List enumNameMappings, CodegenConfigurator configurator) { + for (String propString : enumNameMappings) { + applyEnumNameMappingsKvp(propString, configurator); + } + } + + public static void applyEnumNameMappingsKvp(String enumNameMappings, CodegenConfigurator configurator) { + final Map map = createMapFromKeyValuePairs(enumNameMappings); + for (Map.Entry entry : map.entrySet()) { + configurator.addEnumNameMapping(entry.getKey().trim(), entry.getValue().trim()); + } + } + public static void applyOpenAPINormalizerKvpList(List openapiNormalizer, CodegenConfigurator configurator) { for (String propString : openapiNormalizer) { applyOpenAPINormalizerKvp(propString, configurator); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java index 62b8bda30c7..62be87b6531 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java @@ -1689,6 +1689,10 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code @Override public String toEnumVarName(String value, String datatype) { + if (enumNameMapping.containsKey(value)) { + return enumNameMapping.get(value); + } + if (value.length() == 0) { return "EMPTY"; } diff --git a/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml b/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml index 77bbc979e03..f4332f5fe3b 100644 --- a/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/java/petstore-with-fake-endpoints-models-for-testing-okhttp-gson.yaml @@ -1836,6 +1836,8 @@ components: - placed - approved - delivered + - s + - S OuterEnumInteger: type: integer enum: diff --git a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml index 75e2a80fee9..37b2af48ba6 100644 --- a/samples/client/petstore/java/okhttp-gson/api/openapi.yaml +++ b/samples/client/petstore/java/okhttp-gson/api/openapi.yaml @@ -1861,6 +1861,8 @@ components: - placed - approved - delivered + - s + - S nullable: true type: string OuterEnumInteger: diff --git a/samples/client/petstore/java/okhttp-gson/docs/OuterEnum.md b/samples/client/petstore/java/okhttp-gson/docs/OuterEnum.md index 1f9b723eb8e..e9228f060d2 100644 --- a/samples/client/petstore/java/okhttp-gson/docs/OuterEnum.md +++ b/samples/client/petstore/java/okhttp-gson/docs/OuterEnum.md @@ -11,5 +11,9 @@ * `DELIVERED` (value: `"delivered"`) +* `LOWER_CASE_S` (value: `"s"`) + +* `UPPER_CASE_S` (value: `"S"`) + diff --git a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/OuterEnum.java b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/OuterEnum.java index 97220a992dc..849bfbf8928 100644 --- a/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/OuterEnum.java +++ b/samples/client/petstore/java/okhttp-gson/src/main/java/org/openapitools/client/model/OuterEnum.java @@ -33,7 +33,11 @@ public enum OuterEnum { APPROVED("approved"), - DELIVERED("delivered"); + DELIVERED("delivered"), + + LOWER_CASE_S("s"), + + UPPER_CASE_S("S"); private String value;