Skip to content

Commit 8479978

Browse files
committed
Merge branch 'improve-support-for-nested-parameterobject' of github.com:rudolfgrauberger/springdoc-openapi into rudolfgrauberger-improve-support-for-nested-parameterobject
2 parents 23895a3 + 5ccb9a7 commit 8479978

File tree

10 files changed

+359
-22
lines changed

10 files changed

+359
-22
lines changed

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

+25-22
Original file line numberDiff line numberDiff line change
@@ -128,34 +128,37 @@ private static Stream<MethodParameter> extractFrom(Class<?> clazz, String fieldN
128128
* @return the stream
129129
*/
130130
private static Stream<MethodParameter> fromGetterOfField(Class<?> paramClass, Field field, String fieldNamePrefix) {
131-
if (isSimpleType(field.getType()))
131+
Class<?> type = extractType(paramClass, field);
132+
133+
if (Objects.isNull(type))
134+
return Stream.empty();
135+
136+
if (isSimpleType(type))
132137
return fromSimpleClass(paramClass, field, fieldNamePrefix);
133-
else if (field.getGenericType() instanceof TypeVariable<?>)
134-
return extractTypeParameter(paramClass, (TypeVariable<?>) field.getGenericType(), field, fieldNamePrefix);
135-
else
136-
return extractFrom(field.getType(), fieldNamePrefix + field.getName() + DOT);
138+
else {
139+
String prefix = fieldNamePrefix + field.getName() + DOT;
140+
return extractFrom(type, prefix);
141+
}
137142
}
138143

139144
/**
140-
* Extract type parameter stream.
141-
*
142-
* @param owningClass the owning class
143-
* @param genericType the generic type
144-
* @param field the field
145-
* @param fieldNamePrefix the field name prefix
146-
* @return the stream
145+
* Extract the type
146+
* @param paramClass
147+
* @param field
148+
* @return The revoled type or null if it was not a reifiable type
147149
*/
148-
private static Stream<MethodParameter> extractTypeParameter(
149-
Class<?> owningClass,
150-
TypeVariable<?> genericType,
151-
Field field,
152-
String fieldNamePrefix) {
153-
154-
Type resolvedType = ReturnTypeParser.resolveType(genericType, owningClass);
155-
if (resolvedType instanceof Class<?> && isSimpleType((Class<?>) resolvedType)) {
156-
return fromSimpleClass(owningClass, field, fieldNamePrefix);
150+
private static Class<?> extractType(Class<?> paramClass, Field field) {
151+
Class<?> type = field.getType();
152+
if (field.getGenericType() instanceof TypeVariable<?>) {
153+
Type fieldType = ReturnTypeParser.resolveType(field.getGenericType(), paramClass);
154+
155+
if (fieldType instanceof Class<?>)
156+
type = (Class<?>) fieldType;
157+
else // This is the case for not reifiable types
158+
type = null;
157159
}
158-
return Stream.empty();
160+
161+
return type;
159162
}
160163

161164
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package test.org.springdoc.api.v30.app190;
2+
3+
public class ConcreteSubclassFromGeneric extends SimpleGeneric<MyData> {
4+
private String topName;
5+
6+
public String getTopName() {
7+
return topName;
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * * Copyright 2019-2022 the original author or authors.
6+
* * * *
7+
* * * * Licensed under the Apache License, Version 2.0 (the "License");
8+
* * * * you may not use this file except in compliance with the License.
9+
* * * * You may obtain a copy of the License at
10+
* * * *
11+
* * * * https://www.apache.org/licenses/LICENSE-2.0
12+
* * * *
13+
* * * * Unless required by applicable law or agreed to in writing, software
14+
* * * * distributed under the License is distributed on an "AS IS" BASIS,
15+
* * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* * * * See the License for the specific language governing permissions and
17+
* * * * limitations under the License.
18+
* * *
19+
* *
20+
*
21+
*/
22+
23+
package test.org.springdoc.api.v30.app190;
24+
25+
26+
import org.springdoc.api.annotations.ParameterObject;
27+
import org.springframework.http.HttpStatus;
28+
import org.springframework.http.ResponseEntity;
29+
import org.springframework.web.bind.annotation.GetMapping;
30+
import org.springframework.web.bind.annotation.RestController;
31+
32+
@RestController
33+
public class HelloController {
34+
@GetMapping("/nested")
35+
public ResponseEntity<String> nested(@ParameterObject final SimpleOuterClass filter) {
36+
return new ResponseEntity<>("{\"Say\": \"Hello\"}", HttpStatus.OK);
37+
}
38+
39+
@GetMapping( "/nestedTypeErasureGeneric")
40+
public ResponseEntity<String> nestedTypeErasureGeneric( @ParameterObject final SimpleGeneric<MyData> filter) {
41+
return new ResponseEntity<>("{\"Say\": \"Hello\"}", HttpStatus.OK);
42+
}
43+
44+
@GetMapping( "/nestedReifiableGeneric")
45+
public ResponseEntity<String> nestedReifiableGeneric( @ParameterObject final ConcreteSubclassFromGeneric filter) {
46+
return new ResponseEntity<>("{\"Say\": \"Hello\"}", HttpStatus.OK);
47+
}
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package test.org.springdoc.api.v30.app190;
2+
3+
public class MyData {
4+
private String firstName;
5+
private Integer maxNumber;
6+
7+
public Integer getMaxNumber() {
8+
return maxNumber;
9+
}
10+
11+
public String getFirstName() {
12+
return firstName;
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test.org.springdoc.api.v30.app190;
2+
3+
public class SimpleGeneric<T> {
4+
5+
private String name;
6+
private T child;
7+
8+
public T getChild() {
9+
return child;
10+
}
11+
12+
public String getName() {
13+
return name;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package test.org.springdoc.api.v30.app190;
2+
3+
public class SimpleInnerClass {
4+
5+
private SimpleInnerInnerClass innerInnerClass;
6+
7+
private Boolean name;
8+
private Integer maxNumber;
9+
10+
public Integer getMaxNumber() {
11+
return maxNumber;
12+
}
13+
14+
public Boolean getName() {
15+
return name;
16+
}
17+
18+
public SimpleInnerInnerClass getInnerInnerClass() {
19+
return innerInnerClass;
20+
}
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package test.org.springdoc.api.v30.app190;
2+
3+
public class SimpleInnerInnerClass {
4+
5+
Boolean name;
6+
private Integer maxNumber;
7+
8+
public Integer getMaxNumber() {
9+
return maxNumber;
10+
}
11+
12+
public Boolean getName() {
13+
return name;
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package test.org.springdoc.api.v30.app190;
2+
3+
public class SimpleOuterClass {
4+
private String name;
5+
private SimpleInnerClass innerClass;
6+
7+
public String getName() {
8+
return name;
9+
}
10+
11+
public SimpleInnerClass getInnerClass() {
12+
return innerClass;
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * * Copyright 2019-2022 the original author or authors.
6+
* * * *
7+
* * * * Licensed under the Apache License, Version 2.0 (the "License");
8+
* * * * you may not use this file except in compliance with the License.
9+
* * * * You may obtain a copy of the License at
10+
* * * *
11+
* * * * https://www.apache.org/licenses/LICENSE-2.0
12+
* * * *
13+
* * * * Unless required by applicable law or agreed to in writing, software
14+
* * * * distributed under the License is distributed on an "AS IS" BASIS,
15+
* * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* * * * See the License for the specific language governing permissions and
17+
* * * * limitations under the License.
18+
* * *
19+
* *
20+
*
21+
*/
22+
23+
package test.org.springdoc.api.v30.app190;
24+
25+
import org.springframework.boot.autoconfigure.SpringBootApplication;
26+
import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
27+
28+
public class SpringDocApp190Test extends AbstractSpringDocV30Test {
29+
30+
@SpringBootApplication
31+
static class SpringDocTestApp {}
32+
33+
}

0 commit comments

Comments
 (0)