Skip to content

Commit 994a842

Browse files
[Java] Fix XmlEnumValue generation for URI enums (#24919)
* fix(java): generate valid XmlEnumValue for URI enums * fix(avro-schema): preserve original enum values in rawValue * Update modules/openapi-generator/src/main/resources/JavaJaxRS/cxf/enumClass.mustache Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
1 parent 55059f7 commit 994a842

25 files changed

Lines changed: 184 additions & 22 deletions

File tree

‎modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java‎

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7170,13 +7170,38 @@ protected String getEnumDefaultValue(String defaultValue, String dataType) {
71707170
return enumDefaultValue;
71717171
}
71727172

7173+
/**
7174+
* Builds enum metadata using the original OpenAPI values for both generation and raw metadata.
7175+
*
7176+
* @param values original enum values from the OpenAPI schema; null entries are skipped
7177+
* @param dataType target data type of the enum
7178+
* @return enum entries containing generated names, formatted values, and original raw values
7179+
*/
71737180
protected List<EnumVarMap> buildEnumVars(List<Object> values, String dataType) {
7181+
return buildEnumVars(values, dataType, values);
7182+
}
7183+
7184+
/**
7185+
* Builds enum metadata using separate values for generation and raw metadata.
7186+
*
7187+
* @param values values used to generate enum names and formatted values; null entries are skipped
7188+
* @param dataType target data type of the enum
7189+
* @param rawValues original OpenAPI values, in the same order and with the same number of
7190+
* entries as values; each emitted entry retains its corresponding raw value and type
7191+
* @return enum entries containing generated names, formatted values, and original raw values
7192+
* @throws IllegalArgumentException if the lists have different sizes
7193+
*/
7194+
protected List<EnumVarMap> buildEnumVars(List<Object> values, String dataType, List<Object> rawValues) {
7195+
if (values.size() != rawValues.size()) {
7196+
throw new IllegalArgumentException("values and rawValues must have the same number of entries");
7197+
}
71747198
List<EnumVarMap> enumVars = new ArrayList<>();
71757199
int truncateIdx = isRemoveEnumValuePrefix()
71767200
? findCommonPrefixOfVars(values).length()
71777201
: 0;
71787202

7179-
for (Object value : values) {
7203+
for (int i = 0; i < values.size(); i++) {
7204+
Object value = values.get(i);
71807205
if (value == null) {
71817206
// raw null values in enums are unions for nullable
71827207
// attributes, not actual enum values, so we remove them here
@@ -7194,6 +7219,7 @@ protected List<EnumVarMap> buildEnumVars(List<Object> values, String dataType) {
71947219
final String finalEnumName = toEnumVarName(enumName, dataType);
71957220

71967221
enumVar.enumVar(finalEnumName, toEnumValue(String.valueOf(value), dataType), isDataTypeString(dataType));
7222+
enumVar.setEnumRawValue(rawValues.get(i));
71977223
// TODO: add isNumeric
71987224
enumVars.add(enumVar);
71997225
}
@@ -7227,6 +7253,7 @@ private void injectEnumUnknownDefaultCase(List<EnumVarMap> enumVars, String data
72277253
String.valueOf(11184809);
72287254

72297255
enumVar.enumVar(toEnumVarName(enumName, dataType), toEnumValue(enumValue, dataType), isDataTypeString(dataType));
7256+
enumVar.setEnumRawValue(enumValue);
72307257
// TODO: add isNumeric
72317258
enumVars.add(enumVar);
72327259
}

‎modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,7 +2895,10 @@ protected ImmutableMap.Builder<String, Mustache.Lambda> addMustacheLambdas() {
28952895
writer.write(dataType);
28962896
}
28972897
};
2898+
Mustache.Lambda javaStringLiteralLambda = (fragment, writer) ->
2899+
writer.write(toEnumValue(fragment.execute(), "String"));
28982900
return super.addMustacheLambdas()
2901+
.put("javaStringLiteral", javaStringLiteralLambda)
28992902
.put("jSpecifyDatatype", jSpecifyDatatypeLambda)
29002903
.put("jSpecifyNullable", jSpecifyNullableLambda);
29012904

‎modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AvroSchemaCodegen.java‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,14 +252,16 @@ public String escapeQuotationMark(String input) {
252252
}
253253

254254
@Override
255-
protected List<EnumVarMap> buildEnumVars(List<Object> values, String dataType) {
256-
List<Object> sanitizedValues = values.stream()
257-
.filter(x -> x != null)
255+
protected List<EnumVarMap> buildEnumVars(List<Object> rawValues, String dataType) {
256+
List<Object> originalValues = rawValues.stream()
257+
.filter(Objects::nonNull)
258+
.collect(Collectors.toList());
259+
List<Object> sanitizedValues = originalValues.stream()
258260
.map(Object::toString)
259261
.map(this::sanitizeEnumValue)
260262
.collect(Collectors.toList());
261263
removeEnumValueCollisions(sanitizedValues);
262-
return super.buildEnumVars(sanitizedValues, dataType);
264+
return super.buildEnumVars(sanitizedValues, dataType, originalValues);
263265
}
264266

265267
/**

‎modules/openapi-generator/src/main/java/org/openapitools/codegen/model/EnumVarMap.java‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ public class EnumVarMap extends HashMap<String, Object> {
1212
public static final String ENUM_VARS = "enumVars";
1313
// The name of the enum, for example NAME("value") in Java
1414
public static final String ENUM_NAME = "name";
15-
// The on-the-line value, i.e., the one present in the "values"
15+
// The language-specific value emitted by a template
1616
public static final String ENUM_VALUE = "value";
17+
// The original, unformatted value from the OpenAPI specification
18+
public static final String ENUM_RAW_VALUE = "rawValue";
1719
// If the enum is typed as a string
1820
public static final String ENUM_IS_STRING = "isString";
1921
// The description that should be attached to an entry in "enumVars"
@@ -53,6 +55,14 @@ public Object getEnumValue() {
5355
return get(ENUM_VALUE);
5456
}
5557

58+
public void setEnumRawValue(Object rawValue) {
59+
put(ENUM_RAW_VALUE, rawValue);
60+
}
61+
62+
public Object getEnumRawValue() {
63+
return get(ENUM_RAW_VALUE);
64+
}
65+
5666
public void isString(boolean isString) {
5767
put(ENUM_IS_STRING, isString);
5868
}

‎modules/openapi-generator/src/main/resources/Groovy/modelEnum.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ enum {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEn
99
*/
1010
{{/enumDescription}}
1111
{{#withXml}}
12-
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
12+
@XmlEnumValue({{#lambda.javaStringLiteral}}{{{rawValue}}}{{/lambda.javaStringLiteral}})
1313
{{/withXml}}
1414
{{{name}}}({{{value}}}){{^-last}},
1515
{{/-last}}{{/enumVars}}{{/allowableValues}}

‎modules/openapi-generator/src/main/resources/Java/libraries/microprofile/enumClass.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
1313
{{#allowableValues}}
1414
{{#withXml}}
15-
{{#enumVars}}@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
15+
{{#enumVars}}@XmlEnumValue({{#lambda.javaStringLiteral}}{{{rawValue}}}{{/lambda.javaStringLiteral}}) {{name}}({{^isUri}}{{dataType}}.valueOf({{/isUri}}{{{value}}}{{^isUri}}){{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
1616
{{/withXml}}
1717
{{^withXml}}
1818
{{#enumVars}}{{name}}({{^isUri}}{{dataType}}.valueOf({{/isUri}}{{{value}}}{{^isUri}}){{/isUri}}){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}

‎modules/openapi-generator/src/main/resources/Java/libraries/native/modelEnum.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import java.net.URI;
3434
*/
3535
{{/enumDescription}}
3636
{{#withXml}}
37-
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
37+
@XmlEnumValue({{#lambda.javaStringLiteral}}{{{rawValue}}}{{/lambda.javaStringLiteral}})
3838
{{/withXml}}
3939
{{{name}}}({{{value}}}){{^-last}},
4040
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}

‎modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/modelEnum.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import com.google.gson.stream.JsonWriter;
2323
*/
2424
{{/enumDescription}}
2525
{{#withXml}}
26-
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
26+
@XmlEnumValue({{#lambda.javaStringLiteral}}{{{rawValue}}}{{/lambda.javaStringLiteral}})
2727
{{/withXml}}
2828
{{{name}}}({{{value}}}){{^-last}},
2929
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}

‎modules/openapi-generator/src/main/resources/Java/libraries/okhttp-gson/modelInnerEnum.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
{{/enumDescription}}
1717
{{#withXml}}
18-
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
18+
@XmlEnumValue({{#lambda.javaStringLiteral}}{{{rawValue}}}{{/lambda.javaStringLiteral}})
1919
{{/withXml}}
2020
{{{name}}}({{{value}}}){{^-last}},
2121
{{/-last}}{{#-last}};{{/-last}}

‎modules/openapi-generator/src/main/resources/Java/modelEnum.mustache‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import java.net.URI;
3434
*/
3535
{{/enumDescription}}
3636
{{#withXml}}
37-
@XmlEnumValue({{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isLong}}"{{/isLong}}{{#isFloat}}"{{/isFloat}})
37+
@XmlEnumValue({{#lambda.javaStringLiteral}}{{{rawValue}}}{{/lambda.javaStringLiteral}})
3838
{{/withXml}}
3939
{{{name}}}({{{value}}}){{^-last}},
4040
{{/-last}}{{#-last}};{{/-last}}{{/enumVars}}{{/allowableValues}}

0 commit comments

Comments
 (0)