1
1
package io .avaje .http .generator .core ;
2
2
3
- import java .lang .annotation .Annotation ;
4
- import java .util .ArrayList ;
5
- import java .util .Arrays ;
6
- import java .util .List ;
7
- import java .util .Optional ;
8
- import java .util .function .Predicate ;
9
- import java .util .stream .Collectors ;
10
- import java .util .stream .Stream ;
3
+ import io .avaje .http .api .*;
4
+ import io .avaje .http .generator .core .javadoc .Javadoc ;
5
+ import io .avaje .http .generator .core .openapi .MethodDocBuilder ;
6
+ import io .swagger .v3 .oas .annotations .tags .Tag ;
7
+ import io .swagger .v3 .oas .annotations .tags .Tags ;
11
8
12
9
import javax .lang .model .element .Element ;
13
10
import javax .lang .model .element .ExecutableElement ;
16
13
import javax .lang .model .type .TypeKind ;
17
14
import javax .lang .model .type .TypeMirror ;
18
15
import javax .validation .Valid ;
19
-
20
- import io .avaje .http .api .Delete ;
21
- import io .avaje .http .api .Form ;
22
- import io .avaje .http .api .Get ;
23
- import io .avaje .http .api .OpenAPIResponse ;
24
- import io .avaje .http .api .OpenAPIResponses ;
25
- import io .avaje .http .api .Patch ;
26
- import io .avaje .http .api .Post ;
27
- import io .avaje .http .api .Produces ;
28
- import io .avaje .http .api .Put ;
29
- import io .avaje .http .generator .core .javadoc .Javadoc ;
30
- import io .avaje .http .generator .core .openapi .MethodDocBuilder ;
31
- import io .swagger .v3 .oas .annotations .tags .Tag ;
32
- import io .swagger .v3 .oas .annotations .tags .Tags ;
16
+ import java .lang .annotation .Annotation ;
17
+ import java .util .ArrayList ;
18
+ import java .util .Arrays ;
19
+ import java .util .List ;
20
+ import java .util .Optional ;
21
+ import java .util .function .Predicate ;
22
+ import java .util .stream .Collectors ;
23
+ import java .util .stream .Stream ;
33
24
34
25
public class MethodReader {
35
26
36
27
private final ProcessingContext ctx ;
37
28
private final ControllerReader bean ;
38
29
private final ExecutableElement element ;
39
-
40
30
private final boolean isVoid ;
41
31
private final List <MethodParam > params = new ArrayList <>();
42
-
43
32
private final Javadoc javadoc ;
44
-
45
- private WebMethod webMethod ;
46
- private String webMethodPath ;
47
-
48
- private boolean formMarker ;
49
-
50
33
/**
51
34
* Holds enum Roles that are required for the method.
52
35
*/
53
36
private final List <String > methodRoles ;
54
-
55
37
private final String produces ;
56
-
57
38
private final List <OpenAPIResponse > apiResponses ;
58
-
59
39
private final ExecutableType actualExecutable ;
60
40
private final List <? extends TypeMirror > actualParams ;
61
-
62
41
private final PathSegments pathSegments ;
63
42
private final boolean hasValid ;
64
43
private final List <ExecutableElement > superMethods ;
65
44
45
+ private WebMethod webMethod ;
46
+ private String webMethodPath ;
47
+ private boolean formMarker ;
48
+
66
49
MethodReader (ControllerReader bean , ExecutableElement element , ExecutableType actualExecutable , ProcessingContext ctx ) {
67
50
this .ctx = ctx ;
68
51
this .bean = bean ;
@@ -74,52 +57,50 @@ public class MethodReader {
74
57
this .produces = produces (bean );
75
58
initWebMethodViaAnnotation ();
76
59
77
- this .superMethods =
78
- ctx .getSuperMethods (element .getEnclosingElement (), element .getSimpleName ().toString ());
79
-
80
- superMethods .stream ().forEach (m -> methodRoles .addAll (Util .findRoles (m )));
81
-
82
- this .apiResponses = getApiResponses ();
83
- this .javadoc =
84
- Optional .of (Javadoc .parse (ctx .docComment (element )))
85
- .filter (Predicate .not (Javadoc ::isEmpty ))
86
- .orElseGet (
87
- () ->
88
- superMethods .stream ()
89
- .map (e -> Javadoc .parse (ctx .docComment (e )))
90
- .filter (Predicate .not (Javadoc ::isEmpty ))
91
- .findFirst ()
92
- .orElse (Javadoc .parse ("" )));
60
+ this .superMethods = ctx .superMethods (element .getEnclosingElement (), element .getSimpleName ().toString ());
61
+ superMethods .forEach (m -> methodRoles .addAll (Util .findRoles (m )));
93
62
94
- if (isWebMethod ()) {
63
+ this .apiResponses = buildApiResponses ();
64
+ this .javadoc = buildJavadoc (element , ctx );
95
65
96
- Class <Annotation > jakartaValidAnnotation ;
66
+ if (isWebMethod ()) {
67
+ Class <Annotation > jakartaValidAnnotation ;
97
68
try {
98
69
jakartaValidAnnotation = jakartaValidAnnotation ();
99
70
} catch (final ClassNotFoundException e ) {
100
71
jakartaValidAnnotation = null ;
101
72
}
102
-
103
- final var jakartaAnnotation = jakartaValidAnnotation ;
104
-
105
- this .hasValid =
106
- findAnnotation (Valid .class ) != null
107
- || (jakartaValidAnnotation != null && findAnnotation (jakartaValidAnnotation ) != null )
108
- || superMethods .stream ()
109
- .map (
110
- e ->
111
- findAnnotation (Valid .class , e ) != null
112
- || (jakartaAnnotation != null
113
- && findAnnotation (jakartaAnnotation , e ) != null ))
114
- .anyMatch (b -> b );
115
-
73
+ this .hasValid = hasValid (jakartaValidAnnotation );
116
74
this .pathSegments = PathSegments .parse (Util .combinePath (bean .path (), webMethodPath ));
117
75
} else {
118
76
this .hasValid = false ;
119
77
this .pathSegments = null ;
120
78
}
121
79
}
122
80
81
+ private Javadoc buildJavadoc (ExecutableElement element , ProcessingContext ctx ) {
82
+ return Optional .of (Javadoc .parse (ctx .docComment (element )))
83
+ .filter (Predicate .not (Javadoc ::isEmpty ))
84
+ .orElseGet (() -> superMethods .stream ()
85
+ .map (e -> Javadoc .parse (ctx .docComment (e )))
86
+ .filter (Predicate .not (Javadoc ::isEmpty ))
87
+ .findFirst ()
88
+ .orElse (Javadoc .parse ("" )));
89
+ }
90
+
91
+ private boolean hasValid (Class <Annotation > jakartaValidAnnotation ) {
92
+ return findAnnotation (Valid .class ) != null
93
+ || (jakartaValidAnnotation != null && findAnnotation (jakartaValidAnnotation ) != null )
94
+ || superMethodHasValid (jakartaValidAnnotation );
95
+ }
96
+
97
+ private boolean superMethodHasValid (Class <Annotation > jakartaAnnotation ) {
98
+ return superMethods .stream ()
99
+ .anyMatch (e ->
100
+ findAnnotation (Valid .class , e ) != null
101
+ || (jakartaAnnotation != null && findAnnotation (jakartaAnnotation , e ) != null ));
102
+ }
103
+
123
104
@ SuppressWarnings ("unchecked" )
124
105
private static Class <Annotation > jakartaValidAnnotation () throws ClassNotFoundException {
125
106
return (Class <Annotation >) Class .forName (Valid .class .getCanonicalName ().replace ("javax" , "jakarta" ));
@@ -175,31 +156,30 @@ private String produces(ControllerReader bean) {
175
156
return (produces != null ) ? produces .value () : bean .produces ();
176
157
}
177
158
178
- private List <OpenAPIResponse > getApiResponses () {
159
+ private List <OpenAPIResponse > buildApiResponses () {
179
160
final var container =
180
- Optional .ofNullable (findAnnotation (OpenAPIResponses .class )).stream ()
181
- .map (OpenAPIResponses ::value )
182
- .flatMap (Arrays ::stream );
161
+ Optional .ofNullable (findAnnotation (OpenAPIResponses .class )).stream ()
162
+ .map (OpenAPIResponses ::value )
163
+ .flatMap (Arrays ::stream );
183
164
184
165
final var methodResponses =
185
- Stream .concat (
186
- container , Arrays .stream (element .getAnnotationsByType (OpenAPIResponse .class )));
166
+ Stream .concat (
167
+ container , Arrays .stream (element .getAnnotationsByType (OpenAPIResponse .class )));
187
168
188
169
final var superMethodResponses =
189
- superMethods .stream ()
190
- .flatMap (
191
- m ->
192
- Stream .concat (
193
- Optional .ofNullable (findAnnotation (OpenAPIResponses .class , m )).stream ()
194
- .map (OpenAPIResponses ::value )
195
- .flatMap (Arrays ::stream ),
196
- Arrays .stream (m .getAnnotationsByType (OpenAPIResponse .class ))));
170
+ superMethods .stream ()
171
+ .flatMap (
172
+ method ->
173
+ Stream .concat (
174
+ Optional .ofNullable (findAnnotation (OpenAPIResponses .class , method )).stream ()
175
+ .map (OpenAPIResponses ::value )
176
+ .flatMap (Arrays ::stream ),
177
+ Arrays .stream (method .getAnnotationsByType (OpenAPIResponse .class ))));
197
178
198
179
return Stream .concat (methodResponses , superMethodResponses ).collect (Collectors .toList ());
199
180
}
200
181
201
182
public <A extends Annotation > A findAnnotation (Class <A > type ) {
202
-
203
183
return findAnnotation (type , element );
204
184
}
205
185
@@ -208,28 +188,27 @@ public <A extends Annotation> A findAnnotation(Class<A> type, ExecutableElement
208
188
if (annotation != null ) {
209
189
return annotation ;
210
190
}
211
-
212
191
return bean .findMethodAnnotation (type , elem );
213
192
}
214
193
215
194
private List <String > addTagsToList (Element element , List <String > list ) {
216
- if (element == null )
195
+ if (element == null ) {
217
196
return list ;
218
-
197
+ }
219
198
if (element .getAnnotation (Tag .class ) != null ) {
220
199
list .add (element .getAnnotation (Tag .class ).name ());
221
200
}
222
201
if (element .getAnnotation (Tags .class ) != null ) {
223
- for (Tag tag : element .getAnnotation (Tags .class ).value ())
202
+ for (Tag tag : element .getAnnotation (Tags .class ).value ()) {
224
203
list .add (tag .name ());
204
+ }
225
205
}
226
206
return list ;
227
207
}
228
208
229
209
public List <String > tags () {
230
210
final var tags = addTagsToList (element , new ArrayList <>());
231
- superMethods .forEach (e -> addTagsToList (e , tags ));
232
-
211
+ superMethods .forEach (method -> addTagsToList (method , tags ));
233
212
return addTagsToList (element .getEnclosingElement (), tags );
234
213
}
235
214
0 commit comments