Skip to content

Commit 7e2991c

Browse files
committed
When using ParameterObject, description is taken from superclass instead of subclass. Fixes #2784
1 parent b04a2c0 commit 7e2991c

File tree

12 files changed

+203
-12
lines changed

12 files changed

+203
-12
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ public class DelegatingMethodParameter extends MethodParameter {
8888
*/
8989
private final boolean isParameterObject;
9090

91+
/**
92+
* The Method annotations.
93+
*/
94+
private final Annotation[] methodAnnotations;
95+
9196
/**
9297
* The Is not required.
9398
*/
@@ -99,16 +104,18 @@ public class DelegatingMethodParameter extends MethodParameter {
99104
* @param delegate the delegate
100105
* @param parameterName the parameter name
101106
* @param additionalParameterAnnotations the additional parameter annotations
107+
* @param methodAnnotations the method annotations
102108
* @param isParameterObject the is parameter object
103109
* @param isNotRequired the is required
104110
*/
105-
DelegatingMethodParameter(MethodParameter delegate, String parameterName, Annotation[] additionalParameterAnnotations, boolean isParameterObject, boolean isNotRequired) {
111+
DelegatingMethodParameter(MethodParameter delegate, String parameterName, Annotation[] additionalParameterAnnotations, Annotation[] methodAnnotations, boolean isParameterObject, boolean isNotRequired) {
106112
super(delegate);
107113
this.delegate = delegate;
108114
this.additionalParameterAnnotations = additionalParameterAnnotations;
109115
this.parameterName = parameterName;
110116
this.isParameterObject = isParameterObject;
111117
this.isNotRequired = isNotRequired;
118+
this.methodAnnotations =methodAnnotations;
112119
}
113120

114121
/**
@@ -139,7 +146,7 @@ public static MethodParameter[] customize(String[] pNames, MethodParameter[] par
139146
}
140147
else {
141148
String name = pNames != null ? pNames[i] : p.getParameterName();
142-
explodedParameters.add(new DelegatingMethodParameter(p, name, null, false, false));
149+
explodedParameters.add(new DelegatingMethodParameter(p, name, null, null, false, false));
143150
}
144151
}
145152
return explodedParameters.toArray(new MethodParameter[0]);
@@ -171,7 +178,8 @@ public static MethodParameter changeContainingClass(MethodParameter methodParame
171178
@Override
172179
@NonNull
173180
public Annotation[] getParameterAnnotations() {
174-
return ArrayUtils.addAll(delegate.getParameterAnnotations(), additionalParameterAnnotations);
181+
Annotation[] methodAnnotations = ArrayUtils.addAll(delegate.getParameterAnnotations(), this.methodAnnotations);
182+
return ArrayUtils.addAll(methodAnnotations, additionalParameterAnnotations);
175183
}
176184

177185
@Override

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ private static Stream<MethodParameter> fromSimpleClass(Class<?> paramClass, Fiel
192192
.map(RecordComponent::getAccessor)
193193
.map(method -> new MethodParameter(method, -1))
194194
.map(methodParameter -> DelegatingMethodParameter.changeContainingClass(methodParameter, paramClass))
195-
.map(param -> new DelegatingMethodParameter(param, fieldNamePrefix + field.getName(), fieldAnnotations, true, isNotRequired));
195+
.map(param -> new DelegatingMethodParameter(param, fieldNamePrefix + field.getName(), fieldAnnotations, param.getMethodAnnotations(), true, isNotRequired));
196196

197197
}
198198
else
@@ -202,7 +202,7 @@ private static Stream<MethodParameter> fromSimpleClass(Class<?> paramClass, Fiel
202202
.filter(Objects::nonNull)
203203
.map(method -> new MethodParameter(method, -1))
204204
.map(methodParameter -> DelegatingMethodParameter.changeContainingClass(methodParameter, paramClass))
205-
.map(param -> new DelegatingMethodParameter(param, fieldNamePrefix + field.getName(), fieldAnnotations, true, isNotRequired));
205+
.map(param -> new DelegatingMethodParameter(param, fieldNamePrefix + field.getName(), fieldAnnotations, param.getMethodAnnotations(), true, isNotRequired));
206206
}
207207
catch (IntrospectionException e) {
208208
return Stream.of();

springdoc-openapi-starter-webflux-api/src/test/resources/results/app102.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
{
9292
"name": "nested.param1",
9393
"in": "query",
94+
"description": "nested string parameter",
9495
"required": false,
9596
"schema": {
9697
"type": "string"
@@ -99,6 +100,7 @@
99100
{
100101
"name": "nested.param2",
101102
"in": "query",
103+
"description": "nested BigInteger parameter",
102104
"required": false,
103105
"schema": {
104106
"type": "integer"
@@ -139,4 +141,4 @@
139141
}
140142
}
141143
}
142-
}
144+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package test.org.springdoc.api.v30.app231;
2+
3+
import io.swagger.v3.oas.annotations.Operation;
4+
import org.springdoc.core.annotations.ParameterObject;
5+
6+
import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Application;
7+
import org.springframework.http.MediaType;
8+
import org.springframework.web.bind.annotation.PostMapping;
9+
import org.springframework.web.bind.annotation.RequestBody;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequestMapping(value = "/applications", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
15+
public class ApplicationsRestController {
16+
17+
@Operation(summary = "Parameter object")
18+
@PostMapping("/parameter-object")
19+
public Application createWithParameterObject(
20+
@RequestBody @ParameterObject SubClass request
21+
) {
22+
return new Application();
23+
}
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
*
3+
* *
4+
* * *
5+
* * * *
6+
* * * * *
7+
* * * * * * Copyright 2019-2024 the original author or authors.
8+
* * * * * *
9+
* * * * * * Licensed under the Apache License, Version 2.0 (the "License");
10+
* * * * * * you may not use this file except in compliance with the License.
11+
* * * * * * You may obtain a copy of the License at
12+
* * * * * *
13+
* * * * * * https://www.apache.org/licenses/LICENSE-2.0
14+
* * * * * *
15+
* * * * * * Unless required by applicable law or agreed to in writing, software
16+
* * * * * * distributed under the License is distributed on an "AS IS" BASIS,
17+
* * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* * * * * * See the License for the specific language governing permissions and
19+
* * * * * * limitations under the License.
20+
* * * * *
21+
* * * *
22+
* * *
23+
* *
24+
*
25+
*/
26+
27+
package test.org.springdoc.api.v30.app231;
28+
29+
import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
30+
31+
import org.springframework.boot.autoconfigure.SpringBootApplication;
32+
33+
/**
34+
* @author bnasslahsen
35+
*/
36+
public class SpringDocApp231Test extends AbstractSpringDocV30Test {
37+
38+
@SpringBootApplication
39+
static class SpringDocTestApp {}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package test.org.springdoc.api.v30.app231;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
@Schema(description = "Used to create a new application")
6+
public class SubClass extends SuperClass {
7+
8+
public SubClass(String name) {
9+
super(name);
10+
}
11+
12+
@Override
13+
@Schema(description = "Overriding the description in sub class")
14+
public String getName() {
15+
return super.getName();
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package test.org.springdoc.api.v30.app231;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.Size;
5+
6+
public class SuperClass {
7+
@Size(min = 1, max = 30)
8+
@Schema(description = "Description from the super class")
9+
private String name;
10+
11+
public SuperClass(String name) {
12+
this.name = name;
13+
}
14+
15+
public String getName() {
16+
return name;
17+
}
18+
}

springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app102.json

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
{
8383
"name": "nested.param1",
8484
"in": "query",
85+
"description": "nested string parameter",
8586
"required": false,
8687
"schema": {
8788
"type": "string"
@@ -90,6 +91,7 @@
9091
{
9192
"name": "nested.param2",
9293
"in": "query",
94+
"description": "nested BigInteger parameter",
9395
"required": false,
9496
"schema": {
9597
"type": "integer"

springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app121.json

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
{
9292
"name": "nested.param1",
9393
"in": "query",
94+
"description": "nested string parameter",
9495
"required": false,
9596
"schema": {
9697
"type": "string"
@@ -99,6 +100,7 @@
99100
{
100101
"name": "nested.param2",
101102
"in": "query",
103+
"description": "nested BigInteger parameter",
102104
"required": false,
103105
"schema": {
104106
"type": "integer"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "OpenAPI definition",
5+
"version": "v0"
6+
},
7+
"servers": [
8+
{
9+
"url": "http://localhost",
10+
"description": "Generated server url"
11+
}
12+
],
13+
"paths": {
14+
"/applications/parameter-object": {
15+
"post": {
16+
"tags": [
17+
"applications-rest-controller"
18+
],
19+
"summary": "Parameter object",
20+
"operationId": "createWithParameterObject",
21+
"parameters": [
22+
{
23+
"name": "name",
24+
"in": "query",
25+
"description": "Overriding the description in sub class",
26+
"required": false,
27+
"schema": {
28+
"maxLength": 30,
29+
"minLength": 1,
30+
"type": "string",
31+
"description": "Overriding the description in sub class"
32+
}
33+
}
34+
],
35+
"responses": {
36+
"200": {
37+
"description": "OK",
38+
"content": {
39+
"application/json": {
40+
"schema": {
41+
"$ref": "#/components/schemas/Application"
42+
}
43+
}
44+
}
45+
}
46+
}
47+
}
48+
}
49+
},
50+
"components": {
51+
"schemas": {
52+
"Application": {
53+
"type": "object",
54+
"properties": {
55+
"name": {
56+
"type": "string"
57+
},
58+
"serviceName": {
59+
"type": "string"
60+
},
61+
"clusterName": {
62+
"type": "string"
63+
},
64+
"shardName": {
65+
"type": "string"
66+
},
67+
"customTags": {
68+
"type": "object",
69+
"additionalProperties": {
70+
"type": "string"
71+
}
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}

springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/app102.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
{
104104
"name": "nested.param1",
105105
"in": "query",
106-
"description": "The Param 1.",
106+
"description": "nested string parameter",
107107
"required": false,
108108
"schema": {
109109
"type": "string"
@@ -112,7 +112,7 @@
112112
{
113113
"name": "nested.param2",
114114
"in": "query",
115-
"description": "The Param 2.",
115+
"description": "nested BigInteger parameter",
116116
"required": false,
117117
"schema": {
118118
"type": "integer"
@@ -157,4 +157,4 @@
157157
}
158158
}
159159
}
160-
}
160+
}

springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/app121.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@
103103
{
104104
"name": "nested.param1",
105105
"in": "query",
106-
"description": "The Param 1.",
106+
"description": "nested string parameter",
107107
"required": false,
108108
"schema": {
109109
"type": "string"
@@ -112,7 +112,7 @@
112112
{
113113
"name": "nested.param2",
114114
"in": "query",
115-
"description": "The Param 2.",
115+
"description": "nested BigInteger parameter",
116116
"required": false,
117117
"schema": {
118118
"type": "integer"
@@ -213,4 +213,4 @@
213213
}
214214
}
215215
}
216-
}
216+
}

0 commit comments

Comments
 (0)