Skip to content

Commit b6717a5

Browse files
Zomzogjmini
authored andcommitted
[Java, kotlin] Manage List<Integer> datatype for enum (#75)
1 parent ea81b0c commit b6717a5

File tree

11 files changed

+171
-42
lines changed

11 files changed

+171
-42
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public class CodegenModel {
4444
public String defaultValue;
4545
public String arrayModelType;
4646
public boolean isAlias; // Is this effectively an alias of another simple type
47+
public boolean isString, isInteger;
4748
public List<CodegenProperty> vars = new ArrayList<CodegenProperty>();
4849
public List<CodegenProperty> requiredVars = new ArrayList<CodegenProperty>(); // a list of required properties
4950
public List<CodegenProperty> optionalVars = new ArrayList<CodegenProperty>(); // a list of optional properties

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,11 @@ public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
250250
if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) {
251251
Map<String, Object> allowableValues = cm.allowableValues;
252252
List<Object> values = (List<Object>) allowableValues.get("values");
253-
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
253+
List<Map<String, Object>> enumVars = new ArrayList<Map<String, Object>>();
254254
String commonPrefix = findCommonPrefixOfVars(values);
255255
int truncateIdx = commonPrefix.length();
256256
for (Object value : values) {
257-
Map<String, String> enumVar = new HashMap<String, String>();
257+
Map<String, Object> enumVar = new HashMap<String, Object>();
258258
String enumName;
259259
if (truncateIdx == 0) {
260260
enumName = value.toString();
@@ -266,6 +266,7 @@ public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
266266
}
267267
enumVar.put("name", toEnumVarName(enumName, cm.dataType));
268268
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
269+
enumVar.put("isString", isDataTypeString(cm.dataType));
269270
enumVars.add(enumVar);
270271
}
271272
cm.allowableValues.put("enumVars", enumVars);
@@ -1524,6 +1525,15 @@ public CodegenModel fromModel(String name, Schema schema, Map<String, Schema> al
15241525
if (ModelUtils.isMapSchema(schema)) {
15251526
addAdditionPropertiesToCodeGenModel(m, schema);
15261527
}
1528+
if (ModelUtils.isIntegerSchema(schema)) { // integer type
1529+
if (!ModelUtils.isLongSchema(schema)) { // long type is not integer
1530+
m.isInteger = Boolean.TRUE;
1531+
}
1532+
}
1533+
if (ModelUtils.isStringSchema(schema)){
1534+
m.isString = Boolean.TRUE;
1535+
}
1536+
15271537
addVars(m, unaliasPropertySchema(allDefinitions, schema.getProperties()), schema.getRequired());
15281538
}
15291539

@@ -3678,11 +3688,11 @@ public void updateCodegenPropertyEnum(CodegenProperty var) {
36783688
}
36793689

36803690
// put "enumVars" map into `allowableValues", including `name` and `value`
3681-
List<Map<String, String>> enumVars = new ArrayList<Map<String, String>>();
3691+
List<Map<String, Object>> enumVars = new ArrayList<>();
36823692
String commonPrefix = findCommonPrefixOfVars(values);
36833693
int truncateIdx = commonPrefix.length();
36843694
for (Object value : values) {
3685-
Map<String, String> enumVar = new HashMap<String, String>();
3695+
Map<String, Object> enumVar = new HashMap<>();
36863696
String enumName;
36873697
if (truncateIdx == 0) {
36883698
enumName = value.toString();
@@ -3692,18 +3702,21 @@ public void updateCodegenPropertyEnum(CodegenProperty var) {
36923702
enumName = value.toString();
36933703
}
36943704
}
3695-
enumVar.put("name", toEnumVarName(enumName, var.dataType));
3696-
enumVar.put("value", toEnumValue(value.toString(), var.dataType));
3705+
3706+
final String dataType = var.mostInnerItems != null ? var.mostInnerItems.dataType : var.dataType;
3707+
enumVar.put("name", toEnumVarName(enumName, dataType));
3708+
enumVar.put("value", toEnumValue(value.toString(), dataType));
3709+
enumVar.put("isString", isDataTypeString(dataType));
36973710
enumVars.add(enumVar);
36983711
}
36993712
allowableValues.put("enumVars", enumVars);
37003713

37013714
// handle default value for enum, e.g. available => StatusEnum.AVAILABLE
37023715
if (var.defaultValue != null) {
37033716
String enumName = null;
3704-
for (Map<String, String> enumVar : enumVars) {
3717+
for (Map<String, Object> enumVar : enumVars) {
37053718
if (toEnumValue(var.defaultValue, var.dataType).equals(enumVar.get("value"))) {
3706-
enumName = enumVar.get("name");
3719+
enumName = (String) enumVar.get("name");
37073720
break;
37083721
}
37093722
}
@@ -4362,4 +4375,7 @@ public void generateYAMLSpecFile(Map<String, Object> objs) {
43624375
}
43634376
}
43644377

4378+
public boolean isDataTypeString(String dataType) {
4379+
return "String".equals(dataType);
4380+
}
43654381
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,4 +557,26 @@ protected boolean needToImport(String type) {
557557
boolean imports = !type.startsWith("kotlin.") && !type.startsWith("java.") && !defaultIncludes.contains(type) && !languageSpecificPrimitives.contains(type);
558558
return imports;
559559
}
560+
561+
@Override
562+
public String toEnumValue(String value, String datatype) {
563+
if ("kotlin.Int".equals(datatype) || "kotlin.Long".equals(datatype)) {
564+
return value;
565+
} else if ("kotlin.Double".equals(datatype)) {
566+
if (value.contains(".")) {
567+
return value;
568+
} else {
569+
return value + ".0"; // Float and double must have .0
570+
}
571+
} else if ("kotlin.Float".equals(datatype)) {
572+
return value + "f";
573+
} else {
574+
return "\"" + escapeText(value) + "\"";
575+
}
576+
}
577+
578+
@Override
579+
public boolean isDataTypeString(final String dataType) {
580+
return "String".equals(dataType) || "kotlin.String".equals(dataType);
581+
}
560582
}

modules/openapi-generator/src/main/resources/JavaJaxRS/cxf-cdi/enumClass.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{{classname}}}{{/datatypeWithEnum}} {
44
55
{{#allowableValues}}
6-
{{#enumVars}}@XmlEnumValue({{{value}}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
6+
{{#enumVars}}@XmlEnumValue({{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{name}}({{dataType}}.valueOf({{{value}}})){{^-last}}, {{/-last}}{{#-last}};{{/-last}}{{/enumVars}}
77
{{/allowableValues}}
88

99

@@ -13,7 +13,7 @@ public enum {{#datatypeWithEnum}}{{{.}}}{{/datatypeWithEnum}}{{^datatypeWithEnum
1313
value = v;
1414
}
1515

16-
public String value() {
16+
public {{dataType}} value() {
1717
return value;
1818
}
1919

modules/openapi-generator/src/main/resources/kotlin-client/enum_class.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import com.squareup.moshi.Json
66
*/
77
enum class {{classname}}(val value: {{dataType}}){
88
{{#allowableValues}}{{#enumVars}}
9-
@Json(name = {{{value}}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
9+
@Json(name = {{^isString}}"{{/isString}}{{{value}}}{{^isString}}"{{/isString}}) {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
1010
{{/enumVars}}{{/allowableValues}}
1111
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
import org.testng.annotations.Test;
3434

3535
import java.lang.reflect.Method;
36+
import java.util.Collections;
3637
import java.util.HashMap;
3738
import java.util.HashSet;
39+
import java.util.List;
3840
import java.util.Map;
3941
import java.util.Set;
4042

@@ -202,7 +204,7 @@ public void testEnsureNoDuplicateProduces() {
202204
Assert.assertEquals(co.produces.size(), 1);
203205
Assert.assertEquals(co.produces.get(0).get("mediaType"), "application/json");
204206
}
205-
207+
206208
@Test
207209
public void testGetSchemaTypeWithComposedSchemaWithOneOf() {
208210
final OpenAPI openAPI = new OpenAPIParser().readLocation("src/test/resources/3_0/composed-oneof.yaml", null, new ParseOptions()).getOpenAPI();
@@ -214,4 +216,32 @@ public void testGetSchemaTypeWithComposedSchemaWithOneOf() {
214216

215217
Assert.assertNotNull(type);
216218
}
219+
220+
@Test
221+
public void updateCodegenPropertyEnum() {
222+
final DefaultCodegen codegen = new DefaultCodegen();
223+
CodegenProperty array = codegenPropertyWithArrayOfIntegerValues();
224+
225+
codegen.updateCodegenPropertyEnum(array);
226+
227+
List<Map<String, Object>> enumVars = (List<Map<String, Object>>) array.getItems().getAllowableValues().get("enumVars");
228+
Assert.assertNotNull(enumVars);
229+
Map<String, Object> testedEnumVar = enumVars.get(0);
230+
Assert.assertNotNull(testedEnumVar);
231+
Assert.assertEquals(testedEnumVar.getOrDefault("name", ""),"_1");
232+
Assert.assertEquals(testedEnumVar.getOrDefault("value", ""), "\"1\"");
233+
Assert.assertEquals(testedEnumVar.getOrDefault("isString", ""), false);
234+
}
235+
236+
private CodegenProperty codegenPropertyWithArrayOfIntegerValues() {
237+
CodegenProperty array = new CodegenProperty();
238+
final CodegenProperty items = new CodegenProperty();
239+
final HashMap<String, Object> allowableValues = new HashMap<>();
240+
allowableValues.put("values", Collections.singletonList(1));
241+
items.setAllowableValues(allowableValues);
242+
items.dataType = "Integer";
243+
array.setItems(items);
244+
array.dataType = "Array";
245+
return array;
246+
}
217247
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/AbstractJavaCodegenTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@ public void testAdditionalPropertiesPutForConfigValues() throws Exception {
136136
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xyz.yyyyy.invoker.oooooo");
137137
}
138138

139+
@Test
140+
public void toEnumValue(){
141+
final AbstractJavaCodegen codegen = new P_AbstractJavaCodegen();
142+
Assert.assertEquals(codegen.toEnumValue("1", "Integer"), "1");
143+
Assert.assertEquals(codegen.toEnumValue("42", "Double"), "42");
144+
Assert.assertEquals(codegen.toEnumValue("1337", "Long"), "1337l");
145+
Assert.assertEquals(codegen.toEnumValue("3.14", "Float"), "3.14f");
146+
}
147+
139148
private static class P_AbstractJavaCodegen extends AbstractJavaCodegen {
140149
@Override
141150
public CodegenType getTag() {

modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,7 @@
3434
import io.swagger.v3.parser.core.models.ParseOptions;
3535
import io.swagger.v3.parser.util.SchemaTypeUtil;
3636

37-
import org.openapitools.codegen.CodegenConstants;
38-
import org.openapitools.codegen.CodegenModel;
39-
import org.openapitools.codegen.CodegenModelFactory;
40-
import org.openapitools.codegen.CodegenModelType;
41-
import org.openapitools.codegen.CodegenOperation;
42-
import org.openapitools.codegen.CodegenParameter;
37+
import org.openapitools.codegen.*;
4338
import org.openapitools.codegen.languages.JavaClientCodegen;
4439
import org.openapitools.codegen.utils.ModelUtils;
4540
import org.testng.Assert;
@@ -309,7 +304,7 @@ public void testPackageNamesSetInvokerDerivedFromModel() throws Exception {
309304
Assert.assertEquals(codegen.getInvokerPackage(), "xyz.yyyyy.zzzzzzz.mmmmm");
310305
Assert.assertEquals(codegen.additionalProperties().get(CodegenConstants.INVOKER_PACKAGE), "xyz.yyyyy.zzzzzzz.mmmmm");
311306
}
312-
307+
313308
@Test
314309
public void testGetSchemaTypeWithComposedSchemaWithAllOf() {
315310
final OpenAPI openAPI = new OpenAPIParser().readLocation("src/test/resources/2_0/composed-allof.yaml", null, new ParseOptions()).getOpenAPI();
@@ -321,6 +316,34 @@ public void testGetSchemaTypeWithComposedSchemaWithAllOf() {
321316
Assert.assertEquals(co.allParams.get(0).baseType, "MessageEventCoreWithTimeListEntries");
322317
}
323318

319+
@Test
320+
public void updateCodegenPropertyEnum() {
321+
final JavaClientCodegen codegen = new JavaClientCodegen();
322+
CodegenProperty array = codegenPropertyWithArrayOfIntegerValues();
323+
324+
codegen.updateCodegenPropertyEnum(array);
325+
326+
List<Map<String, String>> enumVars = (List<Map<String, String>>) array.getItems().getAllowableValues().get("enumVars");
327+
Assert.assertNotNull(enumVars);
328+
Map<String, String> testedEnumVar = enumVars.get(0);
329+
Assert.assertNotNull(testedEnumVar);
330+
Assert.assertEquals(testedEnumVar.getOrDefault("name", ""),"NUMBER_1");
331+
Assert.assertEquals(testedEnumVar.getOrDefault("value", ""), "1");
332+
}
333+
334+
private CodegenProperty codegenPropertyWithArrayOfIntegerValues() {
335+
CodegenProperty array = new CodegenProperty();
336+
final CodegenProperty items = new CodegenProperty();
337+
final HashMap<String, Object> allowableValues = new HashMap<>();
338+
allowableValues.put("values", Collections.singletonList(1));
339+
items.setAllowableValues(allowableValues);
340+
items.dataType = "Integer";
341+
array.setItems(items);
342+
array.dataType = "Array";
343+
array.mostInnerItems = items;
344+
return array;
345+
}
346+
324347
private CodegenParameter createPathParam(String name) {
325348
CodegenParameter codegenParameter = createStringParam(name);
326349
codegenParameter.isPathParam = true;

modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/AbstractKotlinCodegenTest.java

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import org.testng.annotations.Test;
77

88
import static org.openapitools.codegen.CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.*;
9+
import static org.testng.Assert.assertEquals;
10+
import static org.testng.Assert.assertFalse;
11+
import static org.testng.Assert.assertTrue;
912

1013
public class AbstractKotlinCodegenTest {
1114

@@ -14,41 +17,51 @@ public class AbstractKotlinCodegenTest {
1417
@Test
1518
public void camlCaseEnumConverter() {
1619
codegen.setEnumPropertyNaming(camelCase.name());
17-
Assert.assertEquals(codegen.toEnumVarName("long Name", null), "longName");
18-
Assert.assertEquals(codegen.toEnumVarName("1long Name", null), "_1longName");
19-
Assert.assertEquals(codegen.toEnumVarName("not1long Name", null), "not1longName");
20+
assertEquals(codegen.toEnumVarName("long Name", null), "longName");
21+
assertEquals(codegen.toEnumVarName("1long Name", null), "_1longName");
22+
assertEquals(codegen.toEnumVarName("not1long Name", null), "not1longName");
2023
}
2124

2225
@Test
2326
public void uppercasEnumConverter() {
2427
codegen.setEnumPropertyNaming(UPPERCASE.name());
25-
Assert.assertEquals(codegen.toEnumVarName("long Name", null), "LONG_NAME");
26-
Assert.assertEquals(codegen.toEnumVarName("1long Name", null), "_1LONG_NAME");
27-
Assert.assertEquals(codegen.toEnumVarName("not1long Name", null), "NOT1LONG_NAME");
28+
assertEquals(codegen.toEnumVarName("long Name", null), "LONG_NAME");
29+
assertEquals(codegen.toEnumVarName("1long Name", null), "_1LONG_NAME");
30+
assertEquals(codegen.toEnumVarName("not1long Name", null), "NOT1LONG_NAME");
2831
}
2932
@Test
3033
public void snake_caseEnumConverter() {
3134
codegen.setEnumPropertyNaming(snake_case.name());
32-
Assert.assertEquals(codegen.toEnumVarName("long Name", null), "long_name");
33-
Assert.assertEquals(codegen.toEnumVarName("1long Name", null), "_1long_name");
34-
Assert.assertEquals(codegen.toEnumVarName("not1long Name", null), "not1long_name");
35+
assertEquals(codegen.toEnumVarName("long Name", null), "long_name");
36+
assertEquals(codegen.toEnumVarName("1long Name", null), "_1long_name");
37+
assertEquals(codegen.toEnumVarName("not1long Name", null), "not1long_name");
3538
}
3639

3740
@Test
3841
public void originalEnumConverter() {
3942
codegen.setEnumPropertyNaming(original.name());
40-
Assert.assertEquals(codegen.toEnumVarName("long Name", null), "long_Name");
41-
Assert.assertEquals(codegen.toEnumVarName("1long Name", null), "_1long_Name");
42-
Assert.assertEquals(codegen.toEnumVarName("not1long Name", null), "not1long_Name");
43+
assertEquals(codegen.toEnumVarName("long Name", null), "long_Name");
44+
assertEquals(codegen.toEnumVarName("1long Name", null), "_1long_Name");
45+
assertEquals(codegen.toEnumVarName("not1long Name", null), "not1long_Name");
4346
}
4447
@Test
4548
public void pascalCaseEnumConverter() {
4649
codegen.setEnumPropertyNaming(PascalCase.name());
47-
Assert.assertEquals(codegen.toEnumVarName("long Name", null), "LongName");
48-
Assert.assertEquals(codegen.toEnumVarName("1long Name", null), "_1longName");
49-
Assert.assertEquals(codegen.toEnumVarName("not1long Name", null), "Not1longName");
50+
assertEquals(codegen.toEnumVarName("long Name", null), "LongName");
51+
assertEquals(codegen.toEnumVarName("1long Name", null), "_1longName");
52+
assertEquals(codegen.toEnumVarName("not1long Name", null), "Not1longName");
5053
}
5154

55+
@Test
56+
public void toEnumValue(){
57+
assertEquals(codegen.toEnumValue("1", "kotlin.Int"), "1");
58+
assertEquals(codegen.toEnumValue("1", "kotlin.Double"), "1.0");
59+
assertEquals(codegen.toEnumValue("1.3", "kotlin.Double"), "1.3");
60+
assertEquals(codegen.toEnumValue("1337", "kotlin.Long"), "1337");
61+
assertEquals(codegen.toEnumValue("5", "kotlin.Float"), "5f");
62+
assertEquals(codegen.toEnumValue("1.0", "kotlin.Float"), "1.0f");
63+
assertEquals(codegen.toEnumValue("data", "Something"), "\"data\"");
64+
}
5265

5366
private class P_AbstractKotlinCodegen extends AbstractKotlinCodegen {
5467
@Override
@@ -66,4 +79,11 @@ public String getHelp() {
6679
return null;
6780
}
6881
}
82+
83+
@Test
84+
public void isDataTypeString(){
85+
assertFalse(codegen.isDataTypeString("kotlin.Int"));
86+
assertTrue(codegen.isDataTypeString("kotlin.String"));
87+
assertTrue(codegen.isDataTypeString("String"));
88+
}
6989
}

modules/openapi-generator/src/test/java/org/openapitools/codegen/php/PhpModelTest.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,14 @@ public void enumArrayModelTest() {
310310
Assert.assertTrue(prope.isEnum);
311311
Assert.assertEquals(prope.allowableValues.get("values"), Arrays.asList("fish", "crab"));
312312

313-
HashMap<String, String> fish= new HashMap<String, String>();
313+
HashMap<String, Object> fish= new HashMap<String, Object>();
314314
fish.put("name", "FISH");
315315
fish.put("value", "\'fish\'");
316-
HashMap<String, String> crab= new HashMap<String, String>();
316+
fish.put("isString", false);
317+
HashMap<String, Object> crab= new HashMap<String, Object>();
317318
crab.put("name", "CRAB");
318319
crab.put("value", "\'crab\'");
320+
crab.put("isString", false);
319321
Assert.assertEquals(prope.allowableValues.get("enumVars"), Arrays.asList(fish, crab));
320322

321323
// assert inner items
@@ -343,12 +345,14 @@ public void enumMdoelValueTest() {
343345
Assert.assertNull(prope.items);
344346
Assert.assertEquals(prope.allowableValues.get("values"), Arrays.asList(1, -1));
345347

346-
HashMap<String, String> one = new HashMap<String, String>();
348+
HashMap<String, Object> one = new HashMap<String, Object>();
347349
one.put("name", "1");
348350
one.put("value", "1");
349-
HashMap<String, String> minusOne = new HashMap<String, String>();
351+
one.put("isString", false);
352+
HashMap<String, Object> minusOne = new HashMap<String, Object>();
350353
minusOne.put("name", "MINUS_1");
351354
minusOne.put("value", "-1");
355+
minusOne.put("isString", false);
352356
Assert.assertEquals(prope.allowableValues.get("enumVars"), Arrays.asList(one, minusOne));
353357
}
354358

0 commit comments

Comments
 (0)