Skip to content

Commit 44acd06

Browse files
authored
Merge pull request #668 from jryan128/used-merged-annotation-for-parameter
Process @parameters method parameters as Spring MergedAnnotations
2 parents f85603e + 503d81c commit 44acd06

File tree

5 files changed

+505
-1
lines changed

5 files changed

+505
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,10 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod,
174174
for (MethodParameter methodParameter : parameters) {
175175
// check if query param
176176
Parameter parameter = null;
177-
io.swagger.v3.oas.annotations.Parameter parameterDoc = methodParameter.getParameterAnnotation(io.swagger.v3.oas.annotations.Parameter.class);
177+
io.swagger.v3.oas.annotations.Parameter parameterDoc = AnnotatedElementUtils.findMergedAnnotation(
178+
AnnotatedElementUtils.forAnnotations(methodParameter.getParameterAnnotations()),
179+
io.swagger.v3.oas.annotations.Parameter.class);
180+
178181
final String pName = methodParameter.getParameterName();
179182
ParameterInfo parameterInfo = new ParameterInfo(pName, methodParameter);
180183

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
package test.org.springdoc.api.app120;
19+
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
import io.swagger.v3.oas.annotations.Parameter;
25+
import io.swagger.v3.oas.annotations.enums.ParameterIn;
26+
import io.swagger.v3.oas.annotations.media.Schema;
27+
import org.springframework.core.annotation.AliasFor;
28+
29+
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
30+
import static java.lang.annotation.ElementType.METHOD;
31+
import static java.lang.annotation.ElementType.PARAMETER;
32+
33+
@Target({PARAMETER, METHOD, ANNOTATION_TYPE})
34+
@Retention(RetentionPolicy.RUNTIME)
35+
@Parameter(description = "non alias description")
36+
public @interface AccountId {
37+
38+
@AliasFor(annotation = Parameter.class, value = "name")
39+
String name() default "";
40+
41+
@AliasFor(annotation = Parameter.class, value = "example")
42+
String example() default "123456";
43+
44+
@AliasFor(annotation = Parameter.class, value = "in")
45+
ParameterIn in() default ParameterIn.DEFAULT;
46+
47+
@AliasFor(annotation = Parameter.class, value = "schema")
48+
Schema schema() default @Schema();
49+
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
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+
package test.org.springdoc.api.app120;
19+
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
import io.swagger.v3.oas.annotations.Parameter;
25+
import io.swagger.v3.oas.annotations.enums.Explode;
26+
import io.swagger.v3.oas.annotations.enums.ParameterIn;
27+
import io.swagger.v3.oas.annotations.enums.ParameterStyle;
28+
import io.swagger.v3.oas.annotations.extensions.Extension;
29+
import io.swagger.v3.oas.annotations.media.ArraySchema;
30+
import io.swagger.v3.oas.annotations.media.Content;
31+
import io.swagger.v3.oas.annotations.media.ExampleObject;
32+
import io.swagger.v3.oas.annotations.media.Schema;
33+
import org.springframework.core.annotation.AliasFor;
34+
import org.springframework.web.bind.annotation.GetMapping;
35+
import org.springframework.web.bind.annotation.PathVariable;
36+
import org.springframework.web.bind.annotation.RequestParam;
37+
import org.springframework.web.bind.annotation.RestController;
38+
39+
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
40+
import static java.lang.annotation.ElementType.METHOD;
41+
import static java.lang.annotation.ElementType.PARAMETER;
42+
43+
@RestController
44+
public class MetaAnnotationController {
45+
46+
@GetMapping(value = "/simpleTest/{accountId}")
47+
String simpleTest(@PathVariable @AccountId String accountId) {
48+
return accountId;
49+
}
50+
51+
/**
52+
* When there is a top level {@code @Parameter} annotation it has precedence over the meta-annotation
53+
* So the id parameter should have all the defaults, with a name of "id"
54+
*/
55+
@GetMapping(value = "/testTopLevelParamAnnotationOverrides/{accountId}")
56+
String testTopLevelParamAnnotationOverrides(@PathVariable @AccountId @Parameter(name = "id") String accountId) {
57+
return accountId;
58+
}
59+
60+
@GetMapping(value = "/testQueryParam")
61+
String testQueryParam(@RequestParam @AccountId String accountId) {
62+
return accountId;
63+
}
64+
65+
/**
66+
* {@code @AliasFor} in the {@code @AccountId} annotation allows us to override the default it provides.
67+
*/
68+
@GetMapping(value = "/testAliasFor")
69+
String testAliasFor(@RequestParam @AccountId(example = "OVERRIDDEN EXAMPLE") String accountId) {
70+
return accountId;
71+
}
72+
73+
/**
74+
* This should inherent all the attributes of {@code @AccountId}, but give it a different name
75+
*/
76+
@Target({PARAMETER, METHOD, ANNOTATION_TYPE})
77+
@Retention(RetentionPolicy.RUNTIME)
78+
@AccountId(name = "queryAccountId")
79+
@interface QueryAccountId {
80+
}
81+
82+
@GetMapping(value = "/testMetaMetaAnnotation/{accountId}")
83+
String testMetaMetaAnnotation(
84+
@RequestParam @QueryAccountId String queryAccountId,
85+
@PathVariable @AccountId String accountId) {
86+
return accountId;
87+
}
88+
89+
@Target({PARAMETER, METHOD, ANNOTATION_TYPE})
90+
@Retention(RetentionPolicy.RUNTIME)
91+
@Parameter
92+
@interface TestAllAttributesAsAlias {
93+
94+
@AliasFor(annotation = Parameter.class, attribute="name")
95+
String name() default "name";
96+
97+
@AliasFor(annotation = Parameter.class, attribute="in")
98+
ParameterIn in() default ParameterIn.QUERY;
99+
100+
@AliasFor(annotation = Parameter.class, attribute="description")
101+
String description() default "desc";
102+
103+
@AliasFor(annotation = Parameter.class, attribute="required")
104+
boolean required() default true;
105+
106+
@AliasFor(annotation = Parameter.class, attribute="deprecated")
107+
boolean deprecated() default true;
108+
109+
@AliasFor(annotation = Parameter.class, attribute="allowEmptyValue")
110+
boolean allowEmptyValue() default true;
111+
112+
@AliasFor(annotation = Parameter.class, attribute="style")
113+
ParameterStyle style() default ParameterStyle.DEEPOBJECT;
114+
115+
@AliasFor(annotation = Parameter.class, attribute="explode")
116+
Explode explode() default Explode.TRUE;
117+
118+
@AliasFor(annotation = Parameter.class, attribute="allowReserved")
119+
boolean allowReserved() default true;
120+
121+
@AliasFor(annotation = Parameter.class, attribute="schema")
122+
Schema schema() default @Schema(name = "special schema", implementation = Boolean.class);
123+
124+
@AliasFor(annotation = Parameter.class, attribute="array")
125+
ArraySchema array() default @ArraySchema();
126+
127+
@AliasFor(annotation = Parameter.class, attribute="content")
128+
Content[] content() default {};
129+
130+
@AliasFor(annotation = Parameter.class, attribute="hidden")
131+
boolean hidden() default false;
132+
133+
@AliasFor(annotation = Parameter.class, attribute="examples")
134+
ExampleObject[] examples() default {};
135+
136+
@AliasFor(annotation = Parameter.class, attribute="example")
137+
String example() default "1234";
138+
139+
@AliasFor(annotation = Parameter.class, attribute="extensions")
140+
Extension[] extensions() default {};
141+
142+
@AliasFor(annotation = Parameter.class, attribute="ref")
143+
String ref() default "";
144+
}
145+
146+
@GetMapping(value = "/testAllAttributesAsAlias/")
147+
String testAllAttributesAsAlias(
148+
@RequestParam @TestAllAttributesAsAlias String name) {
149+
return name;
150+
}
151+
152+
@Target({PARAMETER, METHOD, ANNOTATION_TYPE})
153+
@Retention(RetentionPolicy.RUNTIME)
154+
@Parameter(name = "name", description = "desc", schema = @Schema(implementation = Boolean.class))
155+
@interface TestNoAliasFors {
156+
}
157+
158+
@GetMapping(value = "/testNoAliasFors/")
159+
String testNoAliasFors(
160+
@RequestParam @TestAllAttributesAsAlias String name) {
161+
return name;
162+
}
163+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
package test.org.springdoc.api.app120;
19+
20+
import org.springframework.boot.autoconfigure.SpringBootApplication;
21+
import test.org.springdoc.api.AbstractSpringDocTest;
22+
23+
24+
/**
25+
* Tests Spring meta-annotations as method parameters
26+
*/
27+
public class SpringDocApp120Test extends AbstractSpringDocTest {
28+
29+
@SpringBootApplication
30+
static class SpringDocTestApp {}
31+
}

0 commit comments

Comments
 (0)