Skip to content

Commit aa24c74

Browse files
authored
Check for @JsonNaming in class inheritance (#2402)
Signed-off-by: Michael Edgar <michael@xlate.io>
1 parent 6522c50 commit aa24c74

File tree

3 files changed

+77
-2
lines changed

3 files changed

+77
-2
lines changed

core/src/main/java/io/smallrye/openapi/runtime/scanner/dataobject/TypeResolver.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,11 +1148,30 @@ private static boolean isHigherPriority(Comparator<AnnotationTarget> targetCompa
11481148

11491149
private static UnaryOperator<String> getPropertyNameTranslator(AnnotationScannerContext context, AnnotationTarget target) {
11501150
ClassInfo clazz = target.kind() == Kind.CLASS ? target.asClass() : TypeUtil.getDeclaringClass(target);
1151-
AnnotationInstance jacksonNaming = context.annotations().getAnnotation(clazz, JacksonConstants.JSON_NAMING);
1151+
AugmentedIndexView index = context.getAugmentedIndex();
1152+
Map<ClassInfo, Type> chain = index.inheritanceChain(clazz, Type.create(clazz.name(), Type.Kind.CLASS));
1153+
Annotations annotations = context.annotations();
1154+
AnnotationInstance jacksonNaming = null;
1155+
1156+
for (ClassInfo entry : chain.keySet()) {
1157+
jacksonNaming = annotations.getAnnotation(entry, JacksonConstants.JSON_NAMING);
1158+
1159+
if (jacksonNaming == null) {
1160+
jacksonNaming = index.interfaces(entry)
1161+
.stream()
1162+
.map(index::getClass)
1163+
.filter(Objects::nonNull)
1164+
.map(interfaceClass -> annotations.getAnnotation(interfaceClass, JacksonConstants.JSON_NAMING))
1165+
.filter(Objects::nonNull)
1166+
.findFirst()
1167+
.orElse(null);
1168+
}
1169+
}
1170+
11521171
UnaryOperator<String> translator;
11531172

11541173
if (jacksonNaming != null) {
1155-
Type namingClass = context.annotations().value(jacksonNaming, JacksonConstants.PROP_VALUE);
1174+
Type namingClass = annotations.value(jacksonNaming, JacksonConstants.PROP_VALUE);
11561175

11571176
if (namingClass != null) {
11581177
translator = PropertyNamingStrategyFactory.getStrategy(namingClass.name().toString(), context.getClassLoader());

core/src/test/java/io/smallrye/openapi/runtime/scanner/PropertyNamingStrategyTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.Map;
1212

1313
import org.eclipse.microprofile.config.Config;
14+
import org.eclipse.microprofile.openapi.annotations.media.DiscriminatorMapping;
1415
import org.eclipse.microprofile.openapi.annotations.media.Schema;
1516
import org.eclipse.microprofile.openapi.models.OpenAPI;
1617
import org.junit.jupiter.api.Test;
@@ -194,4 +195,26 @@ public String translate(String value) {
194195
throw new IllegalArgumentException("dummy");
195196
}
196197
}
198+
199+
@JsonNaming(com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy.class)
200+
@Schema(discriminatorProperty = "type", discriminatorMapping = {
201+
@DiscriminatorMapping(value = "bird", schema = Bird.class),
202+
@DiscriminatorMapping(value = "dog", schema = Dog.class),
203+
})
204+
interface Animal {
205+
}
206+
207+
static class Bird implements Animal {
208+
String favoriteSong;
209+
}
210+
211+
static class Dog implements Animal {
212+
String favoriteBall;
213+
}
214+
215+
@Test
216+
void testJacksonNamingInherited() throws Exception {
217+
OpenAPI result = scan(Animal.class, Bird.class, Dog.class);
218+
assertJsonEquals("components.schemas.name-strategy-inherited.json", result);
219+
}
197220
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"openapi" : "3.1.0",
3+
"components" : {
4+
"schemas" : {
5+
"Animal" : {
6+
"discriminator" : {
7+
"propertyName" : "type",
8+
"mapping" : {
9+
"bird" : "#/components/schemas/Bird",
10+
"dog" : "#/components/schemas/Dog"
11+
}
12+
},
13+
"type" : "object"
14+
},
15+
"Bird" : {
16+
"type" : "object",
17+
"properties" : {
18+
"favorite_song" : {
19+
"type" : "string"
20+
}
21+
}
22+
},
23+
"Dog" : {
24+
"type" : "object",
25+
"properties" : {
26+
"favorite_ball" : {
27+
"type" : "string"
28+
}
29+
}
30+
}
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)