Skip to content

Commit 4e57bf0

Browse files
refactor: add DiscriminatorUtils for handling discriminator properties in schemas
1 parent 864e5c0 commit 4e57bf0

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package io.swagger.v3.core.jackson;
2+
3+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
4+
import com.fasterxml.jackson.databind.JavaType;
5+
import io.swagger.v3.core.converter.AnnotatedType;
6+
import io.swagger.v3.core.converter.ModelConverterContext;
7+
import io.swagger.v3.core.util.AnnotationsUtils;
8+
import io.swagger.v3.oas.annotations.media.DiscriminatorMapping;
9+
import io.swagger.v3.oas.models.media.Discriminator;
10+
import io.swagger.v3.oas.models.media.JsonSchema;
11+
import io.swagger.v3.oas.models.media.Schema;
12+
import io.swagger.v3.oas.models.media.StringSchema;
13+
import org.apache.commons.lang3.StringUtils;
14+
15+
import static io.swagger.v3.core.util.RefUtils.constructRef;
16+
17+
class DiscriminatorUtils {
18+
19+
private DiscriminatorUtils() {
20+
}
21+
22+
private static final int SCHEMA_COMPONENT_PREFIX = "#/components/schemas/".length();
23+
private static final String TYPE_STRING = "string";
24+
25+
public static void resolveDiscriminatorProperty(JavaType type,
26+
ModelConverterContext context,
27+
Schema model,
28+
boolean openapi31) {
29+
// add JsonTypeInfo.property if not member of bean
30+
JsonTypeInfo typeInfo = type.getRawClass().getDeclaredAnnotation(JsonTypeInfo.class);
31+
if (typeInfo != null) {
32+
String typeInfoProp = typeInfo.property();
33+
if (StringUtils.isNotBlank(typeInfoProp)) {
34+
Schema modelToUpdate = model;
35+
if (StringUtils.isNotBlank(model.get$ref())) {
36+
modelToUpdate = context.getDefinedModels().get(model.get$ref().substring(SCHEMA_COMPONENT_PREFIX));
37+
}
38+
if (modelToUpdate.getProperties() == null || !modelToUpdate.getProperties().keySet().contains(typeInfoProp)) {
39+
Schema discriminatorSchema = openapi31 ? new JsonSchema().typesItem(TYPE_STRING).name(typeInfoProp) : new StringSchema().name(typeInfoProp);
40+
modelToUpdate.addProperties(typeInfoProp, discriminatorSchema);
41+
if (modelToUpdate.getRequired() == null || !modelToUpdate.getRequired().contains(typeInfoProp)) {
42+
modelToUpdate.addRequiredItem(typeInfoProp);
43+
}
44+
}
45+
}
46+
}
47+
}
48+
49+
public static Discriminator resolveDiscriminator(JavaType type, ModelConverterContext context) {
50+
io.swagger.v3.oas.annotations.media.Schema declaredSchemaAnnotation = AnnotationsUtils.getSchemaDeclaredAnnotation(type.getRawClass());
51+
52+
String disc = (declaredSchemaAnnotation == null) ? "" : declaredSchemaAnnotation.discriminatorProperty();
53+
54+
if (disc.isEmpty()) {
55+
// longer method would involve AnnotationIntrospector.findTypeResolver(...) but:
56+
JsonTypeInfo typeInfo = type.getRawClass().getDeclaredAnnotation(JsonTypeInfo.class);
57+
if (typeInfo != null) {
58+
disc = typeInfo.property();
59+
}
60+
}
61+
if (!disc.isEmpty()) {
62+
Discriminator discriminator = new Discriminator()
63+
.propertyName(disc);
64+
if (declaredSchemaAnnotation != null) {
65+
DiscriminatorMapping[] mappings = declaredSchemaAnnotation.discriminatorMapping();
66+
if (mappings != null && mappings.length > 0) {
67+
for (DiscriminatorMapping mapping : mappings) {
68+
if (!mapping.value().isEmpty() && !mapping.schema().equals(Void.class)) {
69+
discriminator.mapping(mapping.value(), constructRef(context.resolve(new AnnotatedType().type(mapping.schema())).getName()));
70+
}
71+
}
72+
}
73+
}
74+
75+
return discriminator;
76+
}
77+
return null;
78+
}
79+
}

0 commit comments

Comments
 (0)