Skip to content

Commit 3bd0ba0

Browse files
committed
feat: Refactor enum schema generation
Refactor the method for generating enum schemas to better handle type-specific schemas, such as IntegerSchema. This change ensures that integer-based enums are correctly represented in the generated schemas.
1 parent dc8785e commit 3bd0ba0

File tree

5 files changed

+48
-38
lines changed

5 files changed

+48
-38
lines changed

modules/swagger-core/src/main/java/io/swagger/v3/core/jackson/ModelResolver.java

+32-23
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
import io.swagger.v3.oas.models.media.IntegerSchema;
5757
import io.swagger.v3.oas.models.media.JsonSchema;
5858
import io.swagger.v3.oas.models.media.MapSchema;
59-
import io.swagger.v3.oas.models.media.NumberSchema;
6059
import io.swagger.v3.oas.models.media.ObjectSchema;
6160
import io.swagger.v3.oas.models.media.Schema;
6261
import io.swagger.v3.oas.models.media.StringSchema;
@@ -306,8 +305,9 @@ public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context
306305
}
307306

308307
if (model == null && type.isEnumType()) {
309-
model = new StringSchema();
310-
_addEnumProps(type.getRawClass(), model);
308+
@SuppressWarnings("unchecked")
309+
Class<Enum<?>> rawEnumClass = (Class<Enum<?>>) type.getRawClass();
310+
model = _createSchemaForEnum(rawEnumClass);
311311
isPrimitive = true;
312312
}
313313
if (model == null) {
@@ -1164,46 +1164,57 @@ protected boolean _isOptionalType(JavaType propType) {
11641164
/**
11651165
* Adds each enum property value to the model schema
11661166
*
1167-
* @param propClass the enum class for which to add properties
1168-
* @param property the schema to add properties to
1167+
* @param enumClass the enum class for which to add properties
11691168
*/
1170-
protected void _addEnumProps(Class<?> propClass, Schema property) {
1171-
final boolean useIndex = _mapper.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX);
1172-
final boolean useToString = _mapper.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
1169+
protected Schema _createSchemaForEnum(Class<Enum<?>> enumClass) {
1170+
boolean useIndex = _mapper.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX);
1171+
boolean useToString = _mapper.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
11731172

1174-
Optional<Method> jsonValueMethod = Arrays.stream(propClass.getDeclaredMethods())
1173+
Optional<Method> jsonValueMethod = Arrays.stream(enumClass.getDeclaredMethods())
11751174
.filter(m -> m.isAnnotationPresent(JsonValue.class))
11761175
.filter(m -> m.getAnnotation(JsonValue.class).value())
11771176
.findFirst();
11781177

1179-
Optional<Field> jsonValueField = Arrays.stream(propClass.getDeclaredFields())
1178+
Optional<Field> jsonValueField = Arrays.stream(enumClass.getDeclaredFields())
11801179
.filter(f -> f.isAnnotationPresent(JsonValue.class))
11811180
.filter(f -> f.getAnnotation(JsonValue.class).value())
11821181
.findFirst();
11831182

1184-
jsonValueMethod.ifPresent(m -> m.setAccessible(true));
1185-
jsonValueField.ifPresent(m -> m.setAccessible(true));
1186-
@SuppressWarnings("unchecked")
1187-
Class<Enum<?>> enumClass = (Class<Enum<?>>) propClass;
1183+
Schema schema = null;
1184+
if (jsonValueField.isPresent()) {
1185+
jsonValueField.get().setAccessible(true);
1186+
PrimitiveType primitiveType = PrimitiveType.fromType(jsonValueField.get().getType());
1187+
if (primitiveType != null) {
1188+
schema = primitiveType.createProperty();
1189+
}
1190+
} else if (jsonValueMethod.isPresent()) {
1191+
jsonValueMethod.get().setAccessible(true);
1192+
PrimitiveType primitiveType = PrimitiveType.fromType(jsonValueMethod.get().getReturnType());
1193+
if (primitiveType != null) {
1194+
schema = primitiveType.createProperty();
1195+
}
1196+
}
1197+
if (schema == null) {
1198+
schema = new StringSchema();
1199+
}
11881200

11891201
Enum<?>[] enumConstants = enumClass.getEnumConstants();
11901202

11911203
if (enumConstants != null) {
1192-
String[] enumValues = _intr.findEnumValues(propClass, enumConstants,
1204+
String[] enumValues = _intr.findEnumValues(enumClass, enumConstants,
11931205
new String[enumConstants.length]);
11941206

11951207
for (Enum<?> en : enumConstants) {
1196-
String n;
1197-
11981208
Field enumField = ReflectionUtils.findField(en.name(), enumClass);
11991209
if (null != enumField && enumField.isAnnotationPresent(Hidden.class)) {
12001210
continue;
12011211
}
12021212

12031213
String enumValue = enumValues[en.ordinal()];
1204-
String methodValue = jsonValueMethod.flatMap(m -> ReflectionUtils.safeInvoke(m, en)).map(Object::toString).orElse(null);
1205-
String fieldValue = jsonValueField.flatMap(f -> ReflectionUtils.safeGet(f, en)).map(Object::toString).orElse(null);
1214+
Object methodValue = jsonValueMethod.flatMap(m -> ReflectionUtils.safeInvoke(m, en)).orElse(null);
1215+
Object fieldValue = jsonValueField.flatMap(f -> ReflectionUtils.safeGet(f, en)).orElse(null);
12061216

1217+
Object n;
12071218
if (methodValue != null) {
12081219
n = methodValue;
12091220
} else if (fieldValue != null) {
@@ -1217,12 +1228,10 @@ protected void _addEnumProps(Class<?> propClass, Schema property) {
12171228
} else {
12181229
n = _intr.findEnumValue(en);
12191230
}
1220-
if (property instanceof StringSchema) {
1221-
StringSchema sp = (StringSchema) property;
1222-
sp.addEnumItem(n);
1223-
}
1231+
schema.addEnumItemObject(n);
12241232
}
12251233
}
1234+
return schema;
12261235
}
12271236

12281237
protected boolean ignore(final Annotated member, final XmlAccessorType xmlAccessorTypeAnnotation, final String propName, final Set<String> propertiesToIgnore) {

modules/swagger-core/src/test/java/io/swagger/v3/core/converting/EnumPropertyTest.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import io.swagger.v3.core.oas.models.ModelWithEnumProperty;
1313
import io.swagger.v3.core.oas.models.ModelWithEnumRefProperty;
1414
import io.swagger.v3.core.oas.models.ModelWithJacksonEnumField;
15+
import io.swagger.v3.oas.models.media.IntegerSchema;
1516
import io.swagger.v3.oas.models.media.Schema;
1617
import io.swagger.v3.oas.models.media.StringSchema;
1718
import org.testng.annotations.AfterTest;
@@ -216,23 +217,23 @@ public void testExtractJacksonEnumFields() {
216217
assertEquals(secondStringProperty.getEnum(), Arrays.asList("one", "two", "three"));
217218

218219
final Schema thirdEnumProperty = (Schema) model.getProperties().get("thirdEnumValue");
219-
assertTrue(thirdEnumProperty instanceof StringSchema);
220-
final StringSchema thirdStringProperty = (StringSchema) thirdEnumProperty;
221-
assertEquals(thirdStringProperty.getEnum(), Arrays.asList("2", "4", "6"));
220+
assertTrue(thirdEnumProperty instanceof IntegerSchema);
221+
final IntegerSchema thirdStringProperty = (IntegerSchema) thirdEnumProperty;
222+
assertEquals(thirdStringProperty.getEnum(), Arrays.asList(2, 4, 6));
222223

223224
final Schema fourthEnumProperty = (Schema) model.getProperties().get("fourthEnumValue");
224225
assertTrue(fourthEnumProperty instanceof StringSchema);
225226
final StringSchema fourthStringProperty = (StringSchema) fourthEnumProperty;
226-
assertEquals(fourthEnumProperty.getEnum(), Arrays.asList("one", "two", "three"));
227+
assertEquals(fourthStringProperty.getEnum(), Arrays.asList("one", "two", "three"));
227228

228229
final Schema fifthEnumProperty = (Schema) model.getProperties().get("fifthEnumValue");
229-
assertTrue(fifthEnumProperty instanceof StringSchema);
230-
final StringSchema fifthStringProperty = (StringSchema) fifthEnumProperty;
231-
assertEquals(fifthEnumProperty.getEnum(), Arrays.asList("2", "4", "6"));
230+
assertTrue(fifthEnumProperty instanceof IntegerSchema);
231+
final IntegerSchema fifthStringProperty = (IntegerSchema) fifthEnumProperty;
232+
assertEquals(fifthStringProperty.getEnum(), Arrays.asList(2, 4, 6));
232233

233234
final Schema sixthEnumProperty = (Schema) model.getProperties().get("sixthEnumValue");
234235
assertTrue(sixthEnumProperty instanceof StringSchema);
235236
final StringSchema sixthStringProperty = (StringSchema) sixthEnumProperty;
236-
assertEquals(sixthEnumProperty.getEnum(), Arrays.asList("one", "two", "three"));
237+
assertEquals(sixthStringProperty.getEnum(), Arrays.asList("one", "two", "three"));
237238
}
238239
}

modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/JacksonNumberValueEnum.java modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/JacksonIntegerValueEnum.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,20 @@
66
/**
77
* Enum holds values different from names. Schema model will derive Integer value from jackson annotation JsonValue on public method.
88
*/
9-
public enum JacksonNumberValueEnum {
9+
public enum JacksonIntegerValueEnum {
1010
FIRST(2),
1111
SECOND(4),
1212
THIRD(6),
1313
@Hidden HIDDEN(-1);
1414

1515
private final int value;
1616

17-
JacksonNumberValueEnum(int value) {
17+
JacksonIntegerValueEnum(int value) {
1818
this.value = value;
1919
}
2020

2121
@JsonValue
22-
public Number getValue() {
22+
public Integer getValue() {
2323
return value;
2424
}
2525
}

modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/JacksonNumberValueFieldEnum.java modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/JacksonIntegerValueFieldEnum.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/**
77
* Enum holds values different from names. Schema model will derive Integer value from jackson annotation JsonValue on private field.
88
*/
9-
public enum JacksonNumberValueFieldEnum {
9+
public enum JacksonIntegerValueFieldEnum {
1010
FIRST(2),
1111
SECOND(4),
1212
THIRD(6),
@@ -15,7 +15,7 @@ public enum JacksonNumberValueFieldEnum {
1515
@JsonValue
1616
private final int value;
1717

18-
JacksonNumberValueFieldEnum(int value) {
18+
JacksonIntegerValueFieldEnum(int value) {
1919
this.value = value;
2020
}
2121
}

modules/swagger-core/src/test/java/io/swagger/v3/core/oas/models/ModelWithJacksonEnumField.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
public class ModelWithJacksonEnumField {
77
public JacksonPropertyEnum firstEnumValue;
88
public JacksonValueEnum secondEnumValue;
9-
public JacksonNumberValueEnum thirdEnumValue;
9+
public JacksonIntegerValueEnum thirdEnumValue;
1010
public JacksonValueFieldEnum fourthEnumValue;
11-
public JacksonNumberValueFieldEnum fifthEnumValue;
11+
public JacksonIntegerValueFieldEnum fifthEnumValue;
1212
public JacksonValuePrivateEnum sixthEnumValue;
1313
}

0 commit comments

Comments
 (0)