Skip to content

Commit d601fdf

Browse files
authored
Merge pull request #20 from aboutbits/finc-144-fe-rework-api-generator
use proper metadata for swagger additional data
2 parents 67c194b + db0c8c7 commit d601fdf

4 files changed

Lines changed: 224 additions & 131 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package it.aboutbits.springboot.toolbox.swagger;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import lombok.Getter;
6+
import lombok.Setter;
7+
8+
@Getter
9+
@Setter
10+
@JsonInclude(JsonInclude.Include.NON_NULL)
11+
public class SwaggerMeta {
12+
private String originalTypeFqn = null;
13+
@JsonProperty("isIdentity")
14+
private Boolean isIdentity = null;
15+
@JsonProperty("isNestedStructure")
16+
private Boolean isNestedStructure = null;
17+
@JsonProperty("isMap")
18+
private Boolean isMap = null;
19+
private String mapKeyTypeFqn = null;
20+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package it.aboutbits.springboot.toolbox.swagger;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import lombok.NonNull;
6+
import lombok.SneakyThrows;
7+
import lombok.extern.slf4j.Slf4j;
8+
import org.springframework.lang.Nullable;
9+
10+
@Slf4j
11+
public final class SwaggerMetaUtil {
12+
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
13+
14+
private SwaggerMetaUtil() {
15+
}
16+
17+
@SneakyThrows(JsonProcessingException.class)
18+
public static String setMapKeyTypeFqn(@Nullable String currentMeta, @NonNull String value) {
19+
var meta = getSwaggerMeta(currentMeta);
20+
meta.setMapKeyTypeFqn(value);
21+
22+
return OBJECT_MAPPER.writeValueAsString(meta);
23+
}
24+
25+
@SneakyThrows(JsonProcessingException.class)
26+
public static String setIsMap(@Nullable String currentMeta, boolean value) {
27+
var meta = getSwaggerMeta(currentMeta);
28+
meta.setIsMap(!value ? null : true);
29+
30+
return OBJECT_MAPPER.writeValueAsString(meta);
31+
}
32+
33+
@SneakyThrows(JsonProcessingException.class)
34+
public static String setOriginalTypeFqn(@Nullable String currentMeta, @NonNull String value) {
35+
var meta = getSwaggerMeta(currentMeta);
36+
meta.setOriginalTypeFqn(value);
37+
38+
return OBJECT_MAPPER.writeValueAsString(meta);
39+
}
40+
41+
@SneakyThrows(JsonProcessingException.class)
42+
public static String setIsIdentity(@Nullable String currentMeta, boolean value) {
43+
var meta = getSwaggerMeta(currentMeta);
44+
meta.setIsIdentity(!value ? null : true);
45+
46+
return OBJECT_MAPPER.writeValueAsString(meta);
47+
}
48+
49+
@SneakyThrows(JsonProcessingException.class)
50+
public static String setIsNestedStructure(@Nullable String currentMeta, boolean value) {
51+
var meta = getSwaggerMeta(currentMeta);
52+
meta.setIsNestedStructure(!value ? null : true);
53+
54+
return OBJECT_MAPPER.writeValueAsString(meta);
55+
}
56+
57+
private static SwaggerMeta getSwaggerMeta(String currentMeta) {
58+
var meta = new SwaggerMeta();
59+
if (currentMeta != null) {
60+
try {
61+
meta = OBJECT_MAPPER.readValue(currentMeta, SwaggerMeta.class);
62+
} catch (JsonProcessingException e) {
63+
log.warn("error processing meta for swagger: {}", currentMeta);
64+
}
65+
}
66+
return meta;
67+
}
68+
}

src/main/java/it/aboutbits/springboot/toolbox/swagger/type/CustomTypeModelConverter.java

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import io.swagger.v3.core.converter.ModelConverterContext;
66
import io.swagger.v3.oas.models.media.Schema;
77
import it.aboutbits.springboot.toolbox.reflection.util.RecordReflectionUtil;
8+
import it.aboutbits.springboot.toolbox.swagger.SwaggerMetaUtil;
89
import it.aboutbits.springboot.toolbox.type.CustomType;
910
import it.aboutbits.springboot.toolbox.type.ScaledBigDecimal;
11+
import it.aboutbits.springboot.toolbox.type.identity.EntityId;
1012

1113
import java.math.BigDecimal;
1214
import java.math.BigInteger;
@@ -23,36 +25,52 @@ public Schema<?> resolve(
2325

2426
var type = annotatedType.getType();
2527

26-
if (type instanceof Class<?> clazz && CustomType.class.isAssignableFrom(clazz)) {
27-
var constructor = RecordReflectionUtil.getCanonicalConstructor(clazz);
28-
var wrappedType = constructor.getParameters()[0].getType();
28+
if (type instanceof Class<?> clazz) {
29+
Schema<?> result = null;
30+
if (CustomType.class.isAssignableFrom(clazz)) {
31+
var constructor = RecordReflectionUtil.getCanonicalConstructor(clazz);
32+
var wrappedType = constructor.getParameters()[0].getType();
2933

30-
if (Short.class.isAssignableFrom(wrappedType)) {
31-
return context.resolve(new AnnotatedType(Short.TYPE));
32-
}
33-
if (Integer.class.isAssignableFrom(wrappedType)) {
34-
return context.resolve(new AnnotatedType(Integer.TYPE));
35-
}
36-
if (Long.class.isAssignableFrom(wrappedType)) {
37-
return context.resolve(new AnnotatedType(Long.TYPE));
38-
}
39-
if (BigInteger.class.isAssignableFrom(wrappedType)) {
40-
return context.resolve(new AnnotatedType(Long.TYPE));
41-
}
42-
if (Float.class.isAssignableFrom(wrappedType)) {
43-
return context.resolve(new AnnotatedType(Float.TYPE));
44-
}
45-
if (Double.class.isAssignableFrom(wrappedType)) {
46-
return context.resolve(new AnnotatedType(Double.TYPE));
47-
}
48-
if (BigDecimal.class.isAssignableFrom(wrappedType)) {
49-
return context.resolve(new AnnotatedType(Double.TYPE));
50-
}
51-
if (ScaledBigDecimal.class.isAssignableFrom(wrappedType)) {
52-
return context.resolve(new AnnotatedType(Double.TYPE));
53-
}
54-
if (String.class.isAssignableFrom(wrappedType)) {
55-
return context.resolve(new AnnotatedType(String.class));
34+
if (Short.class.isAssignableFrom(wrappedType)) {
35+
result = context.resolve(new AnnotatedType(Short.TYPE));
36+
}
37+
if (Integer.class.isAssignableFrom(wrappedType)) {
38+
result = context.resolve(new AnnotatedType(Integer.TYPE));
39+
}
40+
if (Long.class.isAssignableFrom(wrappedType)) {
41+
result = context.resolve(new AnnotatedType(Long.TYPE));
42+
}
43+
if (BigInteger.class.isAssignableFrom(wrappedType)) {
44+
result = context.resolve(new AnnotatedType(Long.TYPE));
45+
}
46+
if (Float.class.isAssignableFrom(wrappedType)) {
47+
result = context.resolve(new AnnotatedType(Float.TYPE));
48+
}
49+
if (Double.class.isAssignableFrom(wrappedType)) {
50+
result = context.resolve(new AnnotatedType(Double.TYPE));
51+
}
52+
if (BigDecimal.class.isAssignableFrom(wrappedType)) {
53+
result = context.resolve(new AnnotatedType(Double.TYPE));
54+
}
55+
if (ScaledBigDecimal.class.isAssignableFrom(wrappedType)) {
56+
result = context.resolve(new AnnotatedType(Double.TYPE));
57+
}
58+
if (String.class.isAssignableFrom(wrappedType)) {
59+
result = context.resolve(new AnnotatedType(String.class));
60+
}
61+
62+
if (result != null) {
63+
var isIdentity = EntityId.class.isAssignableFrom(clazz);
64+
65+
var description = SwaggerMetaUtil.setOriginalTypeFqn(
66+
result.getDescription(),
67+
((Class<?>) type).getName()
68+
);
69+
description = SwaggerMetaUtil.setIsIdentity(description, isIdentity);
70+
result.setDescription(description);
71+
72+
return result;
73+
}
5674
}
5775
}
5876

src/main/java/it/aboutbits/springboot/toolbox/swagger/type/CustomTypePropertyCustomizer.java

Lines changed: 89 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44
import io.swagger.v3.core.converter.AnnotatedType;
55
import io.swagger.v3.oas.models.media.Schema;
66
import it.aboutbits.springboot.toolbox.reflection.util.RecordReflectionUtil;
7+
import it.aboutbits.springboot.toolbox.swagger.SwaggerMetaUtil;
78
import it.aboutbits.springboot.toolbox.type.CustomType;
89
import it.aboutbits.springboot.toolbox.type.ScaledBigDecimal;
910
import it.aboutbits.springboot.toolbox.type.identity.EntityId;
10-
import lombok.NonNull;
1111
import lombok.extern.slf4j.Slf4j;
1212
import org.springdoc.core.customizers.PropertyCustomizer;
1313

@@ -23,116 +23,103 @@ public Schema<?> customize(Schema property, AnnotatedType annotatedType) {
2323
if (type instanceof SimpleType simpleType) {
2424
var rawClass = simpleType.getRawClass();
2525

26-
// We set the enum name as the description because swagger treats each usage as a new enum.
27-
// This way we can preserve the information about the original enum type.
28-
if (rawClass.isEnum()) {
29-
var displayName = rawClass.getCanonicalName().replace(rawClass.getPackage().getName() + ".", "");
30-
property.setDescription(displayName);
26+
if (rawClass.getName().contains(".") && !rawClass.getName().startsWith("java.")) {
27+
property.setDescription(SwaggerMetaUtil.setOriginalTypeFqn(
28+
property.getDescription(),
29+
rawClass.getName()
30+
));
3131
}
32-
}
33-
34-
if (type instanceof SimpleType simpleType && CustomType.class.isAssignableFrom(simpleType.getRawClass())) {
35-
var rawClass = simpleType.getRawClass();
3632

37-
var displayName = rawClass.getSimpleName();
33+
if (CustomType.class.isAssignableFrom(simpleType.getRawClass())) {
34+
Class<?> wrappedType;
35+
if (rawClass.equals(EntityId.class)) {
36+
wrappedType = simpleType.getBindings().getBoundType(0).getRawClass();
37+
} else {
38+
var constructor = RecordReflectionUtil.getCanonicalConstructor(rawClass);
39+
wrappedType = constructor.getParameters()[0].getType();
40+
}
3841

39-
Class<?> wrappedType;
40-
if (EntityId.class.isAssignableFrom(rawClass)) {
41-
displayName = resolveEntityIdDisplayName(rawClass);
42-
}
42+
var isIdentity = EntityId.class.isAssignableFrom(rawClass);
4343

44-
if (rawClass.equals(EntityId.class)) {
45-
wrappedType = simpleType.getBindings().getBoundType(0).getRawClass();
46-
} else {
47-
var constructor = RecordReflectionUtil.getCanonicalConstructor(rawClass);
48-
wrappedType = constructor.getParameters()[0].getType();
49-
}
44+
var description = SwaggerMetaUtil.setIsIdentity(property.getDescription(), isIdentity);
5045

51-
if (Short.class.isAssignableFrom(wrappedType)) {
52-
property.type("integer");
53-
property.format("");
54-
property.setDescription(displayName);
55-
property.setProperties(null);
56-
property.set$ref(null);
57-
return property;
58-
}
59-
if (Integer.class.isAssignableFrom(wrappedType)) {
60-
property.type("integer");
61-
property.format("int32");
62-
property.setDescription(displayName);
63-
property.setProperties(null);
64-
property.set$ref(null);
65-
return property;
66-
}
67-
if (Long.class.isAssignableFrom(wrappedType)) {
68-
property.type("integer");
69-
property.format("int64");
70-
property.setDescription(displayName);
71-
property.setProperties(null);
72-
property.set$ref(null);
73-
return property;
74-
}
75-
if (BigInteger.class.isAssignableFrom(wrappedType)) {
76-
property.type("integer");
77-
property.format("int64");
78-
property.setDescription(displayName);
79-
property.setProperties(null);
80-
property.set$ref(null);
81-
return property;
82-
}
83-
if (Float.class.isAssignableFrom(wrappedType)) {
84-
property.type("number");
85-
property.format("float");
86-
property.setDescription(displayName);
87-
property.setProperties(null);
88-
property.set$ref(null);
89-
return property;
90-
}
91-
if (Double.class.isAssignableFrom(wrappedType)) {
92-
property.type("number");
93-
property.format("double");
94-
property.setDescription(displayName);
95-
property.setProperties(null);
96-
property.set$ref(null);
97-
return property;
98-
}
99-
if (BigDecimal.class.isAssignableFrom(wrappedType)) {
100-
property.type("number");
101-
property.format("");
102-
property.setDescription(displayName);
103-
property.setProperties(null);
104-
property.set$ref(null);
105-
return property;
106-
}
46+
if (Short.class.isAssignableFrom(wrappedType)) {
47+
property.type("integer");
48+
property.format("");
49+
property.setDescription(description);
50+
property.setProperties(null);
51+
property.set$ref(null);
52+
return property;
53+
}
54+
if (Integer.class.isAssignableFrom(wrappedType)) {
55+
property.type("integer");
56+
property.format("int32");
57+
property.setDescription(description);
58+
property.setProperties(null);
59+
property.set$ref(null);
60+
return property;
61+
}
62+
if (Long.class.isAssignableFrom(wrappedType)) {
63+
property.type("integer");
64+
property.format("int64");
65+
property.setDescription(description);
66+
property.setProperties(null);
67+
property.set$ref(null);
68+
return property;
69+
}
70+
if (BigInteger.class.isAssignableFrom(wrappedType)) {
71+
property.type("integer");
72+
property.format("int64");
73+
property.setDescription(description);
74+
property.setProperties(null);
75+
property.set$ref(null);
76+
return property;
77+
}
78+
if (Float.class.isAssignableFrom(wrappedType)) {
79+
property.type("number");
80+
property.format("float");
81+
property.setDescription(description);
82+
property.setProperties(null);
83+
property.set$ref(null);
84+
return property;
85+
}
86+
if (Double.class.isAssignableFrom(wrappedType)) {
87+
property.type("number");
88+
property.format("double");
89+
property.setDescription(description);
90+
property.setProperties(null);
91+
property.set$ref(null);
92+
return property;
93+
}
94+
if (BigDecimal.class.isAssignableFrom(wrappedType)) {
95+
property.type("number");
96+
property.format("");
97+
property.setDescription(description);
98+
property.setProperties(null);
99+
property.set$ref(null);
100+
return property;
101+
}
107102

108-
if (ScaledBigDecimal.class.isAssignableFrom(wrappedType)) {
109-
property.type("number");
110-
property.format("");
111-
property.setDescription(displayName);
112-
property.setProperties(null);
113-
property.set$ref(null);
114-
return property;
103+
if (ScaledBigDecimal.class.isAssignableFrom(wrappedType)) {
104+
property.type("number");
105+
property.format("");
106+
property.setDescription(description);
107+
property.setProperties(null);
108+
property.set$ref(null);
109+
return property;
110+
}
111+
if (String.class.isAssignableFrom(wrappedType)) {
112+
property.type("string");
113+
property.format(null);
114+
property.setDescription(description);
115+
property.setProperties(null);
116+
property.set$ref(null);
117+
return property;
118+
}
119+
log.warn("Property {} of type WrappedValue: Can not resolve parameter type!", property.getName());
115120
}
116-
if (String.class.isAssignableFrom(wrappedType)) {
117-
property.type("string");
118-
property.format(null);
119-
property.setDescription(displayName);
120-
property.setProperties(null);
121-
property.set$ref(null);
122-
return property;
123-
}
124-
log.warn("Property {} of type WrappedValue: Can not resolve parameter type!", property.getName());
125121
}
126122

127123
return property;
128124
}
129-
130-
@NonNull
131-
private static String resolveEntityIdDisplayName(Class<?> rawClass) {
132-
var parent = rawClass.getEnclosingClass();
133-
if (parent != null) {
134-
return parent.getSimpleName() + "." + rawClass.getSimpleName();
135-
}
136-
return rawClass.getSimpleName();
137-
}
138125
}

0 commit comments

Comments
 (0)