Skip to content

Commit 2d6d816

Browse files
authored
Implemented support for @JsonProperty on enum constants and added regression coverage (#368)
1 parent e2a8e7a commit 2d6d816

2 files changed

Lines changed: 56 additions & 3 deletions

File tree

json-schema-processor/src/main/java/io/micronaut/jsonschema/visitor/JsonSchemaVisitor.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
*/
1616
package io.micronaut.jsonschema.visitor;
1717

18+
import com.fasterxml.jackson.annotation.JsonProperty;
1819
import tools.jackson.databind.ObjectMapper;
1920
import io.micronaut.core.annotation.AnnotationValue;
2021
import io.micronaut.core.annotation.Internal;
2122
import org.jspecify.annotations.NonNull;
2223
import io.micronaut.inject.ast.ClassElement;
24+
import io.micronaut.inject.ast.EnumConstantElement;
2325
import io.micronaut.inject.ast.EnumElement;
2426
import io.micronaut.inject.ast.PropertyElement;
2527
import io.micronaut.inject.ast.TypedElement;
@@ -204,9 +206,8 @@ private static void setSchemaType(TypedElement element, VisitorContext visitorCo
204206
schema.setUniqueItems(true);
205207
}
206208
} else if (!type.isPrimitive() && type.getRawClassElement() instanceof EnumElement enumElement) {
207-
// Enum values must be camel case
208209
schema.addType(Type.STRING)
209-
.setEnumValues(enumElement.values().stream().map(v -> (Object) v).toList());
210+
.setEnumValues(enumValues(enumElement));
210211
context.currentOriginatingElements().add(enumElement);
211212
} else if (type.isAssignable(Number.class)) {
212213
switch (type.getName()) {
@@ -238,6 +239,22 @@ private static void setSchemaType(TypedElement element, VisitorContext visitorCo
238239
}
239240
}
240241

242+
private static List<Object> enumValues(EnumElement enumElement) {
243+
List<EnumConstantElement> enumConstants = enumElement.elements();
244+
if (enumConstants.isEmpty()) {
245+
return enumElement.values().stream().map(v -> (Object) v).toList();
246+
}
247+
return enumConstants.stream().map(JsonSchemaVisitor::enumValue).toList();
248+
}
249+
250+
private static Object enumValue(EnumConstantElement enumConstant) {
251+
AnnotationValue<JsonProperty> jsonProperty = enumConstant.getAnnotation(JsonProperty.class);
252+
if (jsonProperty != null) {
253+
return jsonProperty.stringValue().orElse("");
254+
}
255+
return enumConstant.getName();
256+
}
257+
241258
public static void setBeanSchemaProperties(ClassElement element, VisitorContext visitorContext, JsonSchemaContext context, Schema schema) {
242259
schema.addType(Type.OBJECT);
243260
context.currentOriginatingElements().add(element);

json-schema-processor/src/test/groovy/io/micronaut/jsonschema/visitor/JacksonJsonSchemaVisitorSpec.groovy

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package io.micronaut.jsonschema.visitor
22

33
import io.micronaut.jsonschema.model.Schema
44

5-
65
class JacksonJsonSchemaVisitorSpec extends AbstractJsonSchemaSpec {
76

87
void "schema with jackson property annotations"() {
@@ -32,6 +31,43 @@ class JacksonJsonSchemaVisitorSpec extends AbstractJsonSchemaSpec {
3231
schema.properties['weight (kg)'].type == [Schema.Type.NUMBER]
3332
}
3433

34+
void "schema with JsonProperty annotations on enum constants"() {
35+
given:
36+
def schema = buildJsonSchema('test.Product', 'product', """
37+
package test;
38+
39+
import com.fasterxml.jackson.annotation.*;
40+
import io.micronaut.jsonschema.JsonSchema;
41+
42+
@JsonSchema
43+
public record Product(
44+
PriceType priceType,
45+
MixedType mixedType
46+
) {
47+
}
48+
49+
enum PriceType {
50+
@JsonProperty("M")
51+
meter,
52+
@JsonProperty("K")
53+
kilo
54+
}
55+
56+
enum MixedType {
57+
@JsonProperty("custom")
58+
CUSTOM,
59+
DEFAULT
60+
}
61+
""")
62+
63+
expect:
64+
schema.title == "Product"
65+
schema.properties['priceType'].type == [Schema.Type.STRING]
66+
schema.properties['priceType'].enumValues == ["M", "K"]
67+
schema.properties['mixedType'].type == [Schema.Type.STRING]
68+
schema.properties['mixedType'].enumValues == ["custom", "DEFAULT"]
69+
}
70+
3571
void "schema with subtypes"() {
3672
given:
3773
def schema = buildJsonSchema('test.Reptile', 'reptile', """

0 commit comments

Comments
 (0)