Skip to content

Commit 4a03070

Browse files
author
bnasslahsen
committed
Improve file support
1 parent 22e3e1a commit 4a03070

File tree

3 files changed

+89
-42
lines changed

3 files changed

+89
-42
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterBuilder.java

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,8 @@ Schema calculateSchema(Components components, ParameterInfo parameterInfo, Reque
198198
Class type = methodParameter.getParameterType();
199199

200200
if (parameterInfo.getParameterModel() == null || parameterInfo.getParameterModel().getSchema() == null) {
201-
if (isFile(type)) {
202-
schemaN = getFileSchema(requestBodyInfo);
203-
schemaN.addProperties(paramName, new FileSchema());
204-
return schemaN;
205-
}
206-
else if (methodParameter.getGenericParameterType() instanceof ParameterizedType) {
201+
if (methodParameter.getGenericParameterType() instanceof ParameterizedType) {
207202
ParameterizedType parameterizedType = (ParameterizedType) methodParameter.getGenericParameterType();
208-
if (isFile(parameterizedType))
209-
return extractFileSchema(paramName, requestBodyInfo);
210203
schemaN = SpringDocAnnotationsUtils.extractSchema(components, methodParameter.getGenericParameterType(), jsonView, methodParameter.getParameterAnnotations());
211204
}
212205
else
@@ -220,39 +213,27 @@ else if (methodParameter.getGenericParameterType() instanceof ParameterizedType)
220213
requestBodyInfo.getMergedSchema().addProperties(paramName, schemaN);
221214
schemaN = requestBodyInfo.getMergedSchema();
222215
}
216+
else if (schemaN instanceof FileSchema) {
217+
schemaN = new ObjectSchema().addProperties(paramName, schemaN);
218+
requestBodyInfo.setMergedSchema(schemaN);
219+
}
220+
else if (schemaN instanceof ArraySchema && ((ArraySchema) schemaN).getItems() instanceof FileSchema) {
221+
schemaN = new ObjectSchema().addProperties(paramName, schemaN);
222+
requestBodyInfo.setMergedSchema(schemaN);
223+
}
223224
else
224225
requestBodyInfo.addProperties(paramName, schemaN);
225226
}
226227

227228
return schemaN;
228229
}
229230

230-
public boolean isFile(MethodParameter methodParameter) {
231-
if (methodParameter.getGenericParameterType() instanceof ParameterizedType) {
232-
Type type = methodParameter.getGenericParameterType();
233-
ParameterizedType parameterizedType = (ParameterizedType) type;
234-
return isFile(parameterizedType);
235-
}
236-
else {
237-
Class type = methodParameter.getParameterType();
238-
return isFile(type);
239-
}
240-
}
241-
242231
public boolean isAnnotationToIgnore(MethodParameter parameter) {
243232
return ANNOTATIOSN_TO_IGNORE.stream().anyMatch(
244233
annotation -> parameter.getParameterAnnotation(annotation) != null
245234
|| AnnotationUtils.findAnnotation(parameter.getParameterType(), annotation) != null);
246235
}
247236

248-
private Schema extractFileSchema(String paramName, RequestBodyInfo requestBodyInfo) {
249-
Schema schemaN = getFileSchema(requestBodyInfo);
250-
ArraySchema schemaFile = new ArraySchema();
251-
schemaFile.items(new FileSchema());
252-
schemaN.addProperties(paramName, new ArraySchema().items(new FileSchema()));
253-
return schemaN;
254-
}
255-
256237
private Schema getFileSchema(RequestBodyInfo requestBodyInfo) {
257238
Schema schemaN;
258239
if (requestBodyInfo.getMergedSchema() != null)
@@ -264,19 +245,6 @@ private Schema getFileSchema(RequestBodyInfo requestBodyInfo) {
264245
return schemaN;
265246
}
266247

267-
private boolean isFile(ParameterizedType parameterizedType) {
268-
Type type = parameterizedType.getActualTypeArguments()[0];
269-
Class fileClass = ResolvableType.forType(type).getRawClass();
270-
if (fileClass!=null && isFile(fileClass))
271-
return true;
272-
else if (type instanceof WildcardType) {
273-
WildcardType wildcardType = (WildcardType) type;
274-
Type[] upperBounds = wildcardType.getUpperBounds();
275-
return MultipartFile.class.getName().equals(upperBounds[0].getTypeName());
276-
}
277-
return false;
278-
}
279-
280248
private void setExamples(io.swagger.v3.oas.annotations.Parameter parameterDoc, Parameter parameter) {
281249
Map<String, Example> exampleMap = new HashMap<>();
282250
if (parameterDoc.examples().length == 1 && StringUtils.isBlank(parameterDoc.examples()[0].name())) {
@@ -328,7 +296,31 @@ private boolean isExplodable(io.swagger.v3.oas.annotations.Parameter p) {
328296
return explode;
329297
}
330298

331-
private boolean isFile(Class type) {
299+
public boolean isFile(MethodParameter methodParameter) {
300+
if (methodParameter.getGenericParameterType() instanceof ParameterizedType) {
301+
ParameterizedType parameterizedType = (ParameterizedType) methodParameter.getGenericParameterType();
302+
return isFile(parameterizedType);
303+
}
304+
else {
305+
Class type = methodParameter.getParameterType();
306+
return isFile(type);
307+
}
308+
}
309+
310+
private boolean isFile(ParameterizedType parameterizedType) {
311+
Type type = parameterizedType.getActualTypeArguments()[0];
312+
Class fileClass = ResolvableType.forType(type).getRawClass();
313+
if (fileClass != null && isFile(fileClass))
314+
return true;
315+
else if (type instanceof WildcardType) {
316+
WildcardType wildcardType = (WildcardType) type;
317+
Type[] upperBounds = wildcardType.getUpperBounds();
318+
return MultipartFile.class.getName().equals(upperBounds[0].getTypeName());
319+
}
320+
return false;
321+
}
322+
323+
public static boolean isFile(Class type) {
332324
return FILE_TYPES.stream().anyMatch(clazz -> clazz.isAssignableFrom(type));
333325
}
334326
}

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import io.swagger.v3.oas.models.media.ObjectSchema;
3232
import io.swagger.v3.oas.models.media.Schema;
3333
import org.springdoc.core.converters.AdditionalModelsConverter;
34+
import org.springdoc.core.converters.FileSupportConverter;
3435
import org.springdoc.core.converters.ModelConverterRegistrar;
3536
import org.springdoc.core.converters.PropertyCustomizingConverter;
3637
import org.springdoc.core.converters.ResponseSupportConverter;
@@ -90,6 +91,13 @@ PropertyCustomizingConverter propertyCustomizingConverter(Optional<List<Property
9091
return new PropertyCustomizingConverter(customizers);
9192
}
9293

94+
@Bean
95+
@ConditionalOnMissingBean
96+
@Lazy(false)
97+
FileSupportConverter fileSupportConverter() {
98+
return new FileSupportConverter();
99+
}
100+
93101
@Bean
94102
@ConditionalOnMissingBean
95103
@Lazy(false)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package org.springdoc.core.converters;
20+
21+
22+
import java.util.Iterator;
23+
24+
import com.fasterxml.jackson.databind.JavaType;
25+
import io.swagger.v3.core.converter.AnnotatedType;
26+
import io.swagger.v3.core.converter.ModelConverter;
27+
import io.swagger.v3.core.converter.ModelConverterContext;
28+
import io.swagger.v3.core.util.Json;
29+
import io.swagger.v3.oas.models.media.FileSchema;
30+
import io.swagger.v3.oas.models.media.Schema;
31+
32+
import static org.springdoc.core.GenericParameterBuilder.isFile;
33+
34+
public class FileSupportConverter implements ModelConverter {
35+
36+
@Override
37+
public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterator<ModelConverter> chain) {
38+
JavaType javaType = Json.mapper().constructType(type.getType());
39+
if (javaType != null) {
40+
Class<?> cls = javaType.getRawClass();
41+
if (isFile(cls))
42+
return new FileSchema();
43+
}
44+
return (chain.hasNext()) ? chain.next().resolve(type, context, chain) : null;
45+
}
46+
47+
}

0 commit comments

Comments
 (0)