Skip to content

Commit fad22fe

Browse files
committed
Refactor enum converters
Fixed #2371
1 parent 72408ae commit fad22fe

File tree

9 files changed

+615
-214
lines changed

9 files changed

+615
-214
lines changed

openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautJavaCodegen.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1560,7 +1560,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
15601560
param.isEnum = true;
15611561
}
15621562
if (param.isEnum) {
1563-
addEnumParamsForConverters(modelPackage, param, converterCounters, enumParams, enumImports);
1563+
addEnumParamsForConverters(modelPackage, models.get(param.dataType), param, converterCounters, enumParams, enumImports, false);
15641564
}
15651565
}
15661566
}
@@ -1572,7 +1572,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
15721572
p.isEnum = true;
15731573
}
15741574
if (p.isEnum) {
1575-
addEnumParamsForConverters(modelPackage, p, converterCounters, enumParams, enumImports);
1575+
addEnumParamsForConverters(modelPackage, models.get(p.dataType), p, converterCounters, enumParams, enumImports, false);
15761576
}
15771577
});
15781578
op.formParams.clear();
@@ -1605,7 +1605,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
16051605
}
16061606

16071607
if (param.isEnum && !param.isBodyParam) {
1608-
addEnumParamsForConverters(modelPackage, param, converterCounters, enumParams, enumImports);
1608+
addEnumParamsForConverters(modelPackage, models.get(param.dataType), param, converterCounters, enumParams, enumImports, false);
16091609
}
16101610
}
16111611
if (op.returnProperty != null) {

openapi-generator/src/main/java/io/micronaut/openapi/generator/AbstractMicronautKotlinCodegen.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ protected AbstractMicronautKotlinCodegen() {
413413
typeMapping.put("float", "Float");
414414
typeMapping.put("long", "Long");
415415
typeMapping.put("double", "Double");
416+
typeMapping.put("BigInteger", "BigInteger");
416417
typeMapping.put("ByteArray", "ByteArray");
417418
typeMapping.put("number", "BigDecimal");
418419
typeMapping.put("decimal", "BigDecimal");
@@ -447,6 +448,7 @@ protected AbstractMicronautKotlinCodegen() {
447448

448449
importMapping.put("File", "java.io.File");
449450
importMapping.put("BigDecimal", "java.math.BigDecimal");
451+
importMapping.put("BigInteger", "java.math.BigInteger");
450452
importMapping.put("DateTime", "java.time.Instant");
451453
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
452454
importMapping.put("OffsetDateTime", "java.time.OffsetDateTime");
@@ -1203,7 +1205,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
12031205
param.isEnum = true;
12041206
}
12051207
if (param.isEnum) {
1206-
addEnumParamsForConverters(modelPackage, param, converterCounters, enumParams, enumImports);
1208+
addEnumParamsForConverters(modelPackage, models.get(param.dataType), param, converterCounters, enumParams, enumImports, true);
12071209
}
12081210
}
12091211
}
@@ -1215,7 +1217,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
12151217
p.isEnum = true;
12161218
}
12171219
if (p.isEnum) {
1218-
addEnumParamsForConverters(modelPackage, p, converterCounters, enumParams, enumImports);
1220+
addEnumParamsForConverters(modelPackage, models.get(p.dataType), p, converterCounters, enumParams, enumImports, true);
12191221
}
12201222
});
12211223
op.formParams.clear();
@@ -1254,7 +1256,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
12541256
}
12551257

12561258
if (param.isEnum && !param.isBodyParam) {
1257-
addEnumParamsForConverters(modelPackage, param, converterCounters, enumParams, enumImports);
1259+
addEnumParamsForConverters(modelPackage, models.get(param.dataType), param, converterCounters, enumParams, enumImports, true);
12581260
}
12591261
}
12601262

@@ -1917,14 +1919,16 @@ public String toEnumVarName(String value, String datatype) {
19171919
String varName = value;
19181920

19191921
// number
1920-
if ("Int".equalsIgnoreCase(datatype)
1922+
if (
1923+
"Int".equalsIgnoreCase(datatype)
19211924
|| "Byte".equalsIgnoreCase(datatype)
19221925
|| "Short".equalsIgnoreCase(datatype)
19231926
|| "Integer".equalsIgnoreCase(datatype)
19241927
|| "Long".equalsIgnoreCase(datatype)
19251928
|| "Float".equalsIgnoreCase(datatype)
19261929
|| "Double".equalsIgnoreCase(datatype)
1927-
|| "BigDecimal".equals(datatype)) {
1930+
|| "BigDecimal".equals(datatype)
1931+
) {
19281932
varName = "NUMBER_" + varName;
19291933
varName = varName.replaceAll("-", "MINUS_");
19301934
varName = varName.replaceAll("\\+", "PLUS_");

openapi-generator/src/main/java/io/micronaut/openapi/generator/Utils.java

Lines changed: 96 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,12 @@ public static void processDuplicateVars(List<CodegenProperty> vars) {
618618

619619
public static void addEnumParamsForConverters(
620620
String modelPackage,
621+
CodegenModel enumModel,
621622
CodegenParameter param,
622623
Map<String, Integer> converterCounters,
623624
List<CodegenParameter> enumParams,
624-
List<String> enumImports
625+
List<String> enumImports,
626+
boolean isKotlin
625627
) {
626628
var converterName = param.dataType;
627629
var alreadyAdded = false;
@@ -631,17 +633,101 @@ public static void addEnumParamsForConverters(
631633
break;
632634
}
633635
}
634-
if (!alreadyAdded) {
635-
var counter = converterCounters.get(converterName);
636-
if (counter == null) {
637-
converterCounters.put(converterName, 0);
638-
} else {
639-
converterCounters.put(converterName, counter + 1);
636+
if (alreadyAdded) {
637+
return;
638+
}
639+
640+
var counter = converterCounters.get(converterName);
641+
converterCounters.put(converterName, counter == null ? 0 : counter + 1);
642+
param.vendorExtensions.put("converterName", converterName + (counter != null ? counter : ""));
643+
644+
var convertFun = (enumModel.isNullable ? "Optional.ofNullable(" : "Optional.of(")
645+
+ param.dataType + ".fromValue(" + (isKotlin ? getKotlinEnumConvertFun(enumModel.dataType) : getJavaEnumConvertFun(enumModel.dataType, enumImports)) + "))";
646+
647+
param.vendorExtensions.put("convertFun", convertFun);
648+
param.vendorExtensions.put("convertToStrFun", isKotlin ? getKotlinEnumConvertToStrFun(enumModel.dataType) : getJavaEnumConvertToStrFun((String) enumModel.vendorExtensions.get("baseType")));
649+
enumParams.add(param);
650+
enumImports.add(modelPackage + "." + param.dataType);
651+
}
652+
653+
private static String getKotlinEnumConvertToStrFun(String type) {
654+
return "String".equals(type) ? "v.value" : "v.value.toString()";
655+
}
656+
657+
private static String getJavaEnumConvertToStrFun(String type) {
658+
if ("String".equals(type)) {
659+
return "v.getValue()";
660+
} else if (
661+
"char".equals(type)
662+
|| "byte".equals(type)
663+
|| "short".equals(type)
664+
|| "int".equals(type)
665+
|| "long".equals(type)
666+
|| "float".equals(type)
667+
|| "double".equals(type)
668+
|| "boolean".equals(type)
669+
) {
670+
return "String.valueOf(v.getValue())";
671+
} else {
672+
return "v.getValue().toString()";
673+
}
674+
}
675+
676+
677+
private static String getKotlinEnumConvertFun(String type) {
678+
if ("Char".equals(type)) {
679+
return "v[0]";
680+
} else if ("Byte".equals(type)) {
681+
return "v.toByte()";
682+
} else if ("Short".equals(type)) {
683+
return "v.toShort()";
684+
} else if ("Int".equals(type)) {
685+
return "v.toInt()";
686+
} else if ("Long".equals(type)) {
687+
return "v.toLong()";
688+
} else if ("Float".equals(type)) {
689+
return "v.toFloat()";
690+
} else if ("Double".equals(type)) {
691+
return "v.toDouble()";
692+
} else if ("Boolean".equals(type)) {
693+
return "v.toBoolean()";
694+
} else if ("BigDecimal".equals(type)) {
695+
return "v.toBigDecimal()";
696+
} else if ("BigInteger".equals(type)) {
697+
return "v.toBigInteger()";
698+
}
699+
return "v";
700+
}
701+
702+
private static String getJavaEnumConvertFun(String type, List<String> imports) {
703+
if ("Character".equals(type) || "char".equals(type)) {
704+
return "v.charAt(0)";
705+
} else if ("Byte".equals(type) || "byte".equals(type)) {
706+
return "Byte.valueOf(v)";
707+
} else if ("Short".equals(type) || "short".equals(type)) {
708+
return "Short.valueOf(v)";
709+
} else if ("Integer".equals(type) || "int".equals(type)) {
710+
return "Integer.valueOf(v)";
711+
} else if ("Long".equals(type) || "long".equals(type)) {
712+
return "Long.valueOf(v)";
713+
} else if ("Float".equals(type) || "float".equals(type)) {
714+
return "Float.valueOf(v)";
715+
} else if ("Double".equals(type) || "double".equals(type)) {
716+
return "Double.valueOf(v)";
717+
} else if ("Boolean".equals(type) || "boolean".equals(type)) {
718+
return "Boolean.valueOf(v)";
719+
} else if ("BigDecimal".equals(type)) {
720+
if (!imports.contains("java.math.BigDecimal")) {
721+
imports.add("java.math.BigDecimal");
722+
}
723+
return "new BigDecimal(v)";
724+
} else if ("BigInteger".equals(type)) {
725+
if (!imports.contains("java.math.BigInteger")) {
726+
imports.add("java.math.BigInteger");
640727
}
641-
param.vendorExtensions.put("converterName", converterName + (counter != null ? counter : ""));
642-
enumParams.add(param);
643-
enumImports.add(modelPackage + "." + param.dataType);
728+
return "new BigInteger(v)";
644729
}
730+
return "v";
645731
}
646732

647733
public static boolean addUserParameter(CodegenOperation op, UserParameterMode userParameterMode, boolean isAnonymous, boolean isDenyAll) {

openapi-generator/src/main/resources/templates/java-micronaut/common/EnumConverterConfig.mustache

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,29 @@ package {{invokerPackage}}.config;
44
import io.micronaut.context.annotation.Bean;
55
import io.micronaut.context.annotation.Factory;
66
import io.micronaut.core.convert.TypeConverter;
7-
import io.micronaut.serde.ObjectMapper;
87
{{#generatedAnnotation}}
98
import {{javaxPackage}}.annotation.Generated;
109
{{/generatedAnnotation}}
11-
{{#lombok}}
12-
import lombok.RequiredArgsConstructor;
13-
{{/lombok}}
1410
{{#enumImports}}
1511
import {{{.}}};
1612
{{/enumImports}}
13+
import java.util.Optional;
1714

18-
import java.io.IOException;
19-
20-
{{#lombok}}
21-
@RequiredArgsConstructor
22-
{{/lombok}}
2315
@Factory
2416
{{#generatedAnnotation}}
2517
{{>common/generatedAnnotation}}
2618
{{/generatedAnnotation}}
2719
public class {{{enumConfigClassName}}} {
28-
29-
private final ObjectMapper objectMapper;
30-
{{^lombok}}
31-
32-
public {{{enumConfigClassName}}}(ObjectMapper objectMapper) {
33-
this.objectMapper = objectMapper;
34-
}
35-
{{/lombok}}
3620
{{#enumParams}}
3721

3822
@Bean
3923
public TypeConverter<String, {{{dataType}}}> toEnum{{{vendorExtensions.converterName}}}() {
40-
return commonToEnumConverter({{{dataType}}}.class, objectMapper);
24+
return (v, c, ctx) -> {{{vendorExtensions.convertFun}}};
4125
}
4226

4327
@Bean
4428
public TypeConverter<{{{dataType}}}, String> toStr{{{vendorExtensions.converterName}}}() {
45-
return commonToStrConverter({{{dataType}}}.class, objectMapper);
29+
return (v, c, ctx) -> Optional.of({{{vendorExtensions.convertToStrFun}}});
4630
}
4731
{{/enumParams}}
48-
49-
public static <T> TypeConverter<T, String> commonToStrConverter(Class<T> clazz, ObjectMapper objectMapper) {
50-
return TypeConverter.of(clazz, String.class, (value) -> {
51-
try {
52-
return objectMapper.writeValueAsString(value);
53-
} catch (IOException e) {
54-
throw new RuntimeException(e);
55-
}
56-
});
57-
}
58-
59-
public static <T> TypeConverter<String, T> commonToEnumConverter(Class<T> clazz, ObjectMapper objectMapper) {
60-
return TypeConverter.of(String.class, clazz, (value) -> {
61-
try {
62-
return objectMapper.readValue(value, clazz);
63-
} catch (IOException e) {
64-
throw new RuntimeException(e);
65-
}
66-
});
67-
}
6832
}

openapi-generator/src/main/resources/templates/kotlin-micronaut/common/EnumConverterConfig.mustache

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,52 +4,25 @@ package {{invokerPackage}}.config
44
import io.micronaut.context.annotation.Bean
55
import io.micronaut.context.annotation.Factory
66
import io.micronaut.core.convert.TypeConverter
7-
import io.micronaut.serde.ObjectMapper
87
{{#generatedAnnotation}}
98
import {{javaxPackage}}.annotation.Generated
109
{{/generatedAnnotation}}
1110
{{#enumImports}}
1211
import {{{.}}}
1312
{{/enumImports}}
14-
15-
import java.io.IOException
13+
import java.util.Optional
1614

1715
@Factory
1816
{{#generatedAnnotation}}
1917
{{>common/generatedAnnotation}}
2018
{{/generatedAnnotation}}
21-
class {{{enumConfigClassName}}}(
22-
private val objectMapper: ObjectMapper,
23-
) {
19+
class {{{enumConfigClassName}}} {
2420
{{#enumParams}}
2521

2622
@Bean
27-
fun toEnum{{{vendorExtensions.converterName}}}(): TypeConverter<String, {{{dataType}}}> =
28-
commonToEnumConverter({{{dataType}}}::class.java, objectMapper)
23+
fun toEnum{{{vendorExtensions.converterName}}}() = TypeConverter<String, {{{dataType}}}> { v, _, _ -> {{{vendorExtensions.convertFun}}} }
2924

3025
@Bean
31-
fun toStr{{{vendorExtensions.converterName}}}(): TypeConverter<{{{dataType}}}, String> =
32-
commonToStrConverter({{{dataType}}}::class.java, objectMapper)
26+
fun toStr{{{vendorExtensions.converterName}}}() = TypeConverter<{{{dataType}}}, String> { v, _, _ -> Optional.of({{{vendorExtensions.convertToStrFun}}}) }
3327
{{/enumParams}}
34-
35-
companion object {
36-
37-
fun <T> commonToStrConverter(clazz: Class<T>, objectMapper: ObjectMapper): TypeConverter<T, String> =
38-
TypeConverter.of(clazz, String::class.java) {
39-
try {
40-
objectMapper.writeValueAsString(it)
41-
} catch (e: IOException) {
42-
throw RuntimeException(e)
43-
}
44-
}
45-
46-
fun <T> commonToEnumConverter(clazz: Class<T>, objectMapper: ObjectMapper): TypeConverter<String, T> =
47-
TypeConverter.of(String::class.java, clazz) {
48-
try {
49-
objectMapper.readValue(it, clazz)
50-
} catch (e: IOException) {
51-
throw RuntimeException(e)
52-
}
53-
}
54-
}
5528
}

0 commit comments

Comments
 (0)