Skip to content

Commit fa84aa0

Browse files
author
bnasslahsen
committed
Merge branch 'master' of https://github.com/michaldo/springdoc-openapi into michaldo-master
2 parents 4dd6c9b + 505eee1 commit fa84aa0

File tree

10 files changed

+204
-29
lines changed

10 files changed

+204
-29
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,17 +227,16 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
227227
operation.setOperationId(operationId);
228228
// requests
229229
String[] pNames = this.localSpringDocParameterNameDiscoverer.getParameterNames(handlerMethod.getMethod());
230-
MethodParameter[] parameters = handlerMethod.getMethodParameters();
231230
String[] reflectionParametersNames = Arrays.stream(handlerMethod.getMethod().getParameters()).map(java.lang.reflect.Parameter::getName).toArray(String[]::new);
232231
if (pNames == null || Arrays.stream(pNames).anyMatch(Objects::isNull))
233232
pNames = reflectionParametersNames;
234-
parameters = DelegatingMethodParameter.customize(pNames, parameters, parameterBuilder.getDelegatingMethodParameterCustomizer());
233+
DelegatingMethodParameter[] parameters = DelegatingMethodParameter.customize(pNames, handlerMethod.getMethodParameters(), parameterBuilder.getDelegatingMethodParameterCustomizer());
235234
RequestBodyInfo requestBodyInfo = new RequestBodyInfo();
236235
List<Parameter> operationParameters = (operation.getParameters() != null) ? operation.getParameters() : new ArrayList<>();
237236
Map<String, io.swagger.v3.oas.annotations.Parameter> parametersDocMap = getApiParameters(handlerMethod.getMethod());
238237
Components components = openAPI.getComponents();
239238

240-
for (MethodParameter methodParameter : parameters) {
239+
for (DelegatingMethodParameter methodParameter : parameters) {
241240
// check if query param
242241
Parameter parameter = null;
243242
io.swagger.v3.oas.annotations.Parameter parameterDoc = AnnotatedElementUtils.findMergedAnnotation(
@@ -353,7 +352,7 @@ protected Parameter customiseParameter(Parameter parameter, ParameterInfo parame
353352
* @param parameter the parameter
354353
* @return the boolean
355354
*/
356-
public boolean isParamToIgnore(MethodParameter parameter) {
355+
public boolean isParamToIgnore(DelegatingMethodParameter parameter) {
357356
if (SpringDocAnnotationsUtils.isAnnotationToIgnore(parameter))
358357
return true;
359358
if (isRequiredAnnotation(parameter))

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

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import java.util.List;
3232
import java.util.Objects;
3333
import java.util.Optional;
34-
import java.util.stream.Stream;
3534

3635
import org.apache.commons.lang3.ArrayUtils;
3736
import org.springdoc.api.annotations.ParameterObject;
@@ -69,6 +68,12 @@ public class DelegatingMethodParameter extends MethodParameter {
6968
*/
7069
private boolean isParameterObject;
7170

71+
/**
72+
* For simple parameters, it is null
73+
* For nested parameter is a controller method parameter
74+
*/
75+
private MethodParameter controllerMethodParameter;
76+
7277
/**
7378
* Instantiates a new Delegating method parameter.
7479
*
@@ -93,29 +98,24 @@ public class DelegatingMethodParameter extends MethodParameter {
9398
* @param optionalDelegatingMethodParameterCustomizer the optional delegating method parameter customizer
9499
* @return the method parameter [ ]
95100
*/
96-
public static MethodParameter[] customize(String[] pNames, MethodParameter[] parameters, Optional<DelegatingMethodParameterCustomizer> optionalDelegatingMethodParameterCustomizer) {
97-
List<MethodParameter> explodedParameters = new ArrayList<>();
101+
public static DelegatingMethodParameter[] customize(String[] pNames, MethodParameter[] parameters, Optional<DelegatingMethodParameterCustomizer> optionalDelegatingMethodParameterCustomizer) {
102+
List<DelegatingMethodParameter> explodedParameters = new ArrayList<>();
98103
for (int i = 0; i < parameters.length; ++i) {
99104
MethodParameter p = parameters[i];
100105
Class<?> paramClass = AdditionalModelsConverter.getReplacement(p.getParameterType());
101106
if (p.hasParameterAnnotation(ParameterObject.class) || AnnotatedElementUtils.isAnnotated(paramClass, ParameterObject.class)) {
102-
Stream<MethodParameter> methodParameterStream = MethodParameterPojoExtractor.extractFrom(paramClass);
103-
if (!optionalDelegatingMethodParameterCustomizer.isPresent())
104-
MethodParameterPojoExtractor.extractFrom(paramClass).forEach(explodedParameters::add);
105-
else {
106-
DelegatingMethodParameterCustomizer delegatingMethodParameterCustomizer = optionalDelegatingMethodParameterCustomizer.get();
107-
methodParameterStream.forEach(methodParameter -> {
108-
delegatingMethodParameterCustomizer.customize(p, methodParameter);
109-
explodedParameters.add(methodParameter);
110-
});
111-
}
107+
MethodParameterPojoExtractor.extractFrom(paramClass).forEach(delegatingMethodParameter -> {
108+
optionalDelegatingMethodParameterCustomizer.ifPresent(customizer -> customizer.customize(p, delegatingMethodParameter));
109+
delegatingMethodParameter.setControllerMethodParameter(p);
110+
explodedParameters.add(delegatingMethodParameter);
111+
});
112112
}
113113
else {
114114
String name = pNames != null ? pNames[i] : p.getParameterName();
115115
explodedParameters.add(new DelegatingMethodParameter(p, name, null, false));
116116
}
117117
}
118-
return explodedParameters.toArray(new MethodParameter[0]);
118+
return explodedParameters.toArray(new DelegatingMethodParameter[0]);
119119
}
120120

121121
@Override
@@ -220,4 +220,14 @@ public int hashCode() {
220220
public boolean isParameterObject() {
221221
return isParameterObject;
222222
}
223+
224+
public void setControllerMethodParameter(MethodParameter controllerMethodParameter) {
225+
this.controllerMethodParameter = controllerMethodParameter;
226+
}
227+
228+
public MethodParameter getControllerMethodParameter() {
229+
return controllerMethodParameter == null ? delegate : controllerMethodParameter;
230+
}
231+
232+
223233
}

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private MethodParameterPojoExtractor() {
9494
* @param clazz the clazz
9595
* @return the stream
9696
*/
97-
static Stream<MethodParameter> extractFrom(Class<?> clazz) {
97+
static Stream<DelegatingMethodParameter> extractFrom(Class<?> clazz) {
9898
return extractFrom(clazz, "");
9999
}
100100

@@ -105,7 +105,7 @@ static Stream<MethodParameter> extractFrom(Class<?> clazz) {
105105
* @param fieldNamePrefix the field name prefix
106106
* @return the stream
107107
*/
108-
private static Stream<MethodParameter> extractFrom(Class<?> clazz, String fieldNamePrefix) {
108+
private static Stream<DelegatingMethodParameter> extractFrom(Class<?> clazz, String fieldNamePrefix) {
109109
return allFieldsOf(clazz).stream()
110110
.flatMap(f -> fromGetterOfField(clazz, f, fieldNamePrefix))
111111
.filter(Objects::nonNull);
@@ -119,7 +119,7 @@ private static Stream<MethodParameter> extractFrom(Class<?> clazz, String fieldN
119119
* @param fieldNamePrefix the field name prefix
120120
* @return the stream
121121
*/
122-
private static Stream<MethodParameter> fromGetterOfField(Class<?> paramClass, Field field, String fieldNamePrefix) {
122+
private static Stream<DelegatingMethodParameter> fromGetterOfField(Class<?> paramClass, Field field, String fieldNamePrefix) {
123123
if (isSimpleType(field.getType()))
124124
return fromSimpleClass(paramClass, field, fieldNamePrefix);
125125
else
@@ -134,7 +134,7 @@ private static Stream<MethodParameter> fromGetterOfField(Class<?> paramClass, Fi
134134
* @param fieldNamePrefix the field name prefix
135135
* @return the stream
136136
*/
137-
private static Stream<MethodParameter> fromSimpleClass(Class<?> paramClass, Field field, String fieldNamePrefix) {
137+
private static Stream<DelegatingMethodParameter> fromSimpleClass(Class<?> paramClass, Field field, String fieldNamePrefix) {
138138
Annotation[] fieldAnnotations = field.getDeclaredAnnotations();
139139
try {
140140
Nullable nullableField = NULLABLE_ANNOTATION;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,9 @@ public static void mergeSchema(Content existingContent, Schema<?> schemaN, Strin
231231
* @return the boolean
232232
*/
233233
@SuppressWarnings("unchecked")
234-
public static boolean isAnnotationToIgnore(MethodParameter parameter) {
234+
public static boolean isAnnotationToIgnore(DelegatingMethodParameter parameter) {
235235
return ANNOTATIONS_TO_IGNORE.stream().anyMatch(
236-
annotation -> parameter.getParameterAnnotation(annotation) != null
236+
annotation -> AnnotationUtils.findAnnotation(parameter.getControllerMethodParameter().getParameter(), annotation) != null
237237
|| AnnotationUtils.findAnnotation(parameter.getParameterType(), annotation) != null);
238238
}
239239

springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestRequestBuilder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ public void buildParameters(Class<?> domainType, OpenAPI openAPI, HandlerMethod
133133
* @param methodAttributes the method attributes
134134
* @param operation the operation
135135
* @param pNames the p names
136-
* @param parameters the parameters
136+
* @param methodParameters the parameters
137137
*/
138-
public void buildCommonParameters(Class<?> domainType, OpenAPI openAPI, RequestMethod requestMethod, MethodAttributes methodAttributes, Operation operation, String[] pNames, MethodParameter[] parameters) {
139-
parameters = DelegatingMethodParameter.customize(pNames, parameters, parameterBuilder.getDelegatingMethodParameterCustomizer());
140-
for (MethodParameter methodParameter : parameters) {
138+
public void buildCommonParameters(Class<?> domainType, OpenAPI openAPI, RequestMethod requestMethod, MethodAttributes methodAttributes, Operation operation, String[] pNames, MethodParameter[] methodParameters) {
139+
DelegatingMethodParameter[] parameters = DelegatingMethodParameter.customize(pNames, methodParameters, parameterBuilder.getDelegatingMethodParameterCustomizer());
140+
for (DelegatingMethodParameter methodParameter : parameters) {
141141
final String pName = methodParameter.getParameterName();
142142
ParameterInfo parameterInfo = new ParameterInfo(pName, methodParameter);
143143
if (isParamToIgnore(methodParameter)) {
@@ -171,7 +171,7 @@ else if (methodParameter.getParameterAnnotation(BackendId.class) != null) {
171171
* @param methodParameter the method parameter
172172
* @return the boolean
173173
*/
174-
private boolean isParamToIgnore(MethodParameter methodParameter) {
174+
private boolean isParamToIgnore(DelegatingMethodParameter methodParameter) {
175175
return !requestBuilder.isParamToIgnore(methodParameter)
176176
&& !isHeaderToIgnore(methodParameter)
177177
&& !"property".equals(methodParameter.getParameterName());
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package test.org.springdoc.api.app7;
2+
3+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
4+
5+
import java.lang.annotation.Documented;
6+
import java.lang.annotation.ElementType;
7+
import java.lang.annotation.Retention;
8+
import java.lang.annotation.RetentionPolicy;
9+
import java.lang.annotation.Target;
10+
11+
@Target({ElementType.PARAMETER, ElementType.TYPE})
12+
@Retention(RetentionPolicy.RUNTIME)
13+
@Documented
14+
@AuthenticationPrincipal
15+
public @interface CurrentUser {
16+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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 test.org.springdoc.api.app7;
20+
21+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
22+
import org.springframework.web.bind.annotation.PostMapping;
23+
import org.springframework.web.bind.annotation.RestController;
24+
25+
@RestController
26+
public class HelloController {
27+
28+
@PostMapping(value = "/hello")
29+
public String hello(
30+
@AuthenticationPrincipal Person person1,
31+
@CurrentUser Person person2) {
32+
return "OK";
33+
}
34+
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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 test.org.springdoc.api.app7;
20+
21+
public class Person {
22+
23+
private String name;
24+
25+
public Person() {
26+
}
27+
28+
public String getName() {
29+
return name;
30+
}
31+
32+
public void setName(String name) {
33+
this.name = name;
34+
}
35+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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 test.org.springdoc.api.app7;
20+
21+
import io.swagger.v3.oas.models.OpenAPI;
22+
import io.swagger.v3.oas.models.info.Info;
23+
import io.swagger.v3.oas.models.info.License;
24+
import org.springframework.boot.autoconfigure.SpringBootApplication;
25+
import org.springframework.context.annotation.Bean;
26+
import test.org.springdoc.api.AbstractSpringDocTest;
27+
28+
public class SpringDocApp7Test extends AbstractSpringDocTest {
29+
30+
@SpringBootApplication(scanBasePackages = { "test.org.springdoc.api.configuration,test.org.springdoc.api.app7" })
31+
static class SpringDocTestApp {
32+
@Bean
33+
public OpenAPI customOpenAPI() {
34+
return new OpenAPI()
35+
.info(new Info().title("Security API").version("v1")
36+
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
37+
}
38+
}
39+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "Security API",
5+
"license": {
6+
"name": "Apache 2.0",
7+
"url": "http://springdoc.org"
8+
},
9+
"version": "v1"
10+
},
11+
"servers": [
12+
{
13+
"url": "http://localhost",
14+
"description": "Generated server url"
15+
}
16+
],
17+
"paths": {
18+
"/hello": {
19+
"post": {
20+
"tags": [
21+
"hello-controller"
22+
],
23+
"operationId": "hello",
24+
"responses": {
25+
"200": {
26+
"description": "OK",
27+
"content": {
28+
"*/*": {
29+
"schema": {
30+
"type": "string"
31+
}
32+
}
33+
}
34+
}
35+
}
36+
}
37+
}
38+
},
39+
"components": {
40+
}
41+
}

0 commit comments

Comments
 (0)