Skip to content

Commit

Permalink
Add enum name mapping to Java generators (#17018)
Browse files Browse the repository at this point in the history
* add enum name mapping to java generators

* update doc

* update description
  • Loading branch information
wing328 authored Nov 13, 2023
1 parent 7e52992 commit ec3c484
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 2 deletions.
3 changes: 3 additions & 0 deletions bin/configs/java-okhttp-gson.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ additionalProperties:
hideGenerationTimestamp: "true"
useOneOfDiscriminatorLookup: "true"
disallowAdditionalPropertiesIfNotPresent: false
enumNameMappings:
s: LOWER_CASE_S
S: UPPER_CASE_S
8 changes: 7 additions & 1 deletion docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -542,6 +545,18 @@ private void generatePlainTextHelp(StringBuilder sb, CodegenConfig config) {
sb.append(newline);
}

if (Boolean.TRUE.equals(enumNameMappings)) {
sb.append(newline).append("ENUM NAME MAPPING").append(newline).append(newline);
Map<String, String> 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<String, String> map = config.openapiNormalizer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@ public class Generate extends OpenApiGeneratorCommand {
+ " You can also have multiple occurrences of this option.")
private List<String> 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<String> enumNameMappings = new ArrayList<>();

@Option(
name = {"--openapi-normalizer"},
title = "OpenAPI normalizer rules",
Expand Down Expand Up @@ -492,6 +499,7 @@ public void execute() {
applyNameMappingsKvpList(nameMappings, configurator);
applyParameterNameMappingsKvpList(parameterNameMappings, configurator);
applyModelNameMappingsKvpList(modelNameMappings, configurator);
applyEnumNameMappingsKvpList(enumNameMappings, configurator);
applyOpenAPINormalizerKvpList(openapiNormalizer, configurator);
applyTypeMappingsKvpList(typeMappings, configurator);
applyAdditionalPropertiesKvpList(additionalProperties, configurator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public final class GeneratorSettings implements Serializable {
private final Map<String, String> nameMappings;
private final Map<String, String> parameterNameMappings;
private final Map<String, String> modelNameMappings;
private final Map<String, String> enumNameMappings;
private final Map<String, String> openapiNormalizer;
private final Set<String> languageSpecificPrimitives;
private final Map<String, String> reservedWordsMappings;
Expand Down Expand Up @@ -295,6 +296,15 @@ public Map<String, String> getModelNameMappings() {
return modelNameMappings;
}

/**
* Gets enum name mappings between an enum name and the new name.
*
* @return the enum name mappings
*/
public Map<String, String> getEnumNameMappings() {
return enumNameMappings;
}

/**
* Gets OpenAPI normalizer rules
*
Expand Down Expand Up @@ -425,6 +435,7 @@ private GeneratorSettings(Builder builder) {
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);
Expand Down Expand Up @@ -502,6 +513,7 @@ public GeneratorSettings() {
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));
Expand Down Expand Up @@ -572,6 +584,9 @@ public static Builder newBuilder(GeneratorSettings copy) {
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());
}
Expand Down Expand Up @@ -620,6 +635,7 @@ public static final class Builder {
private Map<String, String> nameMappings;
private Map<String, String> parameterNameMappings;
private Map<String, String> modelNameMappings;
private Map<String, String> enumNameMappings;
private Map<String, String> openapiNormalizer;
private Set<String> languageSpecificPrimitives;
private Map<String, String> reservedWordsMappings;
Expand All @@ -644,6 +660,7 @@ public Builder() {
nameMappings = new HashMap<>();
parameterNameMappings = new HashMap<>();
modelNameMappings = new HashMap<>();
enumNameMappings = new HashMap<>();
openapiNormalizer = new HashMap<>();
languageSpecificPrimitives = new HashSet<>();
reservedWordsMappings = new HashMap<>();
Expand Down Expand Up @@ -1043,6 +1060,32 @@ public Builder withModelNameMapping(String key, String value) {
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<String, String> 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.
*
Expand Down Expand Up @@ -1259,6 +1302,7 @@ public boolean equals(Object o) {
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()) &&
Expand Down Expand Up @@ -1294,6 +1338,7 @@ public int hashCode() {
getNameMappings(),
getParameterNameMappings(),
getModelNameMappings(),
getEnumNameMappings(),
getOpenAPINormalizer(),
getLanguageSpecificPrimitives(),
getReservedWordsMappings(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ open class OpenApiGeneratorGenerateExtension(project: Project) {
*/
val modelNameMappings = project.objects.mapProperty<String, String>()

/**
* Specifies mappings between an enum name and the new name
*/
val enumNameMappings = project.objects.mapProperty<String, String>()

/**
* Specifies mappings (rules) in OpenAPI normalizer
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,13 @@ open class GenerateTask @Inject constructor(private val objectFactory: ObjectFac
@Input
val modelNameMappings = project.objects.mapProperty<String, String>()

/**
* Specifies mappings between the enum name and the new name
*/
@Optional
@Input
val enumNameMappings = project.objects.mapProperty<String, String>()

/**
* Specifies mappings (rules) in OpenAPI normalizer
*/
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ public class CodeGenMojo extends AbstractMojo {
@Parameter(name = "modelNameMappings", property = "openapi.generator.maven.plugin.modelNameMappings")
private List<String> modelNameMappings;

/**
* A map of enum names and the new names
*/
@Parameter(name = "enumNameMappings", property = "openapi.generator.maven.plugin.enumNameMappings")
private List<String> enumNameMappings;

/**
* A set of rules for OpenAPI normalizer
*/
Expand Down Expand Up @@ -834,6 +840,11 @@ public void execute() throws MojoExecutionException {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ public interface CodegenConfig {

Map<String, String> modelNameMapping();

Map<String, String> enumNameMapping();

Map<String, String> openapiNormalizer();

Map<String, String> apiTemplateFiles();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ public class DefaultCodegen implements CodegenConfig {
protected Map<String, String> parameterNameMapping = new HashMap<>();
// a map to store the mapping between model name and the name provided by the user
protected Map<String, String> modelNameMapping = new HashMap<>();
// a map to store the mapping between enum name and the name provided by the user
protected Map<String, String> enumNameMapping = new HashMap<>();
// a map to store the rules in OpenAPI Normalizer
protected Map<String, String> openapiNormalizer = new HashMap<>();
protected String modelPackage = "", apiPackage = "", fileSuffix;
Expand Down Expand Up @@ -1244,6 +1246,11 @@ public Map<String, String> modelNameMapping() {
return modelNameMapping;
}

@Override
public Map<String, String> enumNameMapping() {
return enumNameMapping;
}

@Override
public Map<String, String> openapiNormalizer() {
return openapiNormalizer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public class CodegenConfigurator {
private Map<String, String> nameMappings = new HashMap<>();
private Map<String, String> parameterNameMappings = new HashMap<>();
private Map<String, String> modelNameMappings = new HashMap<>();
private Map<String, String> enumNameMappings = new HashMap<>();
private Map<String, String> openapiNormalizer = new HashMap<>();
private Set<String> languageSpecificPrimitives = new HashSet<>();
private Map<String, String> reservedWordsMappings = new HashMap<>();
Expand Down Expand Up @@ -136,6 +137,9 @@ public static CodegenConfigurator fromFile(String configFile, Module... modules)
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());
}
Expand Down Expand Up @@ -244,6 +248,12 @@ public CodegenConfigurator addModelNameMapping(String key, String value) {
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);
Expand Down Expand Up @@ -440,6 +450,12 @@ public CodegenConfigurator setModelNameMappings(Map<String, String> modelNameMap
return this;
}

public CodegenConfigurator setEnumNameMappings(Map<String, String> enumNameMappings) {
this.enumNameMappings = enumNameMappings;
generatorSettingsBuilder.withEnumNameMappings(enumNameMappings);
return this;
}

public CodegenConfigurator setOpenAPINormalizer(Map<String, String> openapiNormalizer) {
this.openapiNormalizer = openapiNormalizer;
generatorSettingsBuilder.withOpenAPINormalizer(openapiNormalizer);
Expand Down Expand Up @@ -728,6 +744,7 @@ public ClientOptInput toClientOptInput() {
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,19 @@ public static void applyModelNameMappingsKvp(String modelNameMappings, CodegenCo
}
}

public static void applyEnumNameMappingsKvpList(List<String> enumNameMappings, CodegenConfigurator configurator) {
for (String propString : enumNameMappings) {
applyEnumNameMappingsKvp(propString, configurator);
}
}

public static void applyEnumNameMappingsKvp(String enumNameMappings, CodegenConfigurator configurator) {
final Map<String, String> map = createMapFromKeyValuePairs(enumNameMappings);
for (Map.Entry<String, String> entry : map.entrySet()) {
configurator.addEnumNameMapping(entry.getKey().trim(), entry.getValue().trim());
}
}

public static void applyOpenAPINormalizerKvpList(List<String> openapiNormalizer, CodegenConfigurator configurator) {
for (String propString : openapiNormalizer) {
applyOpenAPINormalizerKvp(propString, configurator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,10 @@ public String toEnumName(CodegenProperty property) {

@Override
public String toEnumVarName(String value, String datatype) {
if (enumNameMapping.containsKey(value)) {
return enumNameMapping.get(value);
}

if (value.length() == 0) {
return "EMPTY";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,8 @@ components:
- placed
- approved
- delivered
- s
- S
OuterEnumInteger:
type: integer
enum:
Expand Down
2 changes: 2 additions & 0 deletions samples/client/petstore/java/okhttp-gson/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1861,6 +1861,8 @@ components:
- placed
- approved
- delivered
- s
- S
nullable: true
type: string
OuterEnumInteger:
Expand Down
4 changes: 4 additions & 0 deletions samples/client/petstore/java/okhttp-gson/docs/OuterEnum.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@

* `DELIVERED` (value: `"delivered"`)

* `LOWER_CASE_S` (value: `"s"`)

* `UPPER_CASE_S` (value: `"S"`)



Loading

0 comments on commit ec3c484

Please sign in to comment.