10
10
import static java .util .function .Predicate .not ;
11
11
12
12
import java .util .ArrayList ;
13
+ import java .util .HashSet ;
14
+ import java .util .Iterator ;
13
15
import java .util .List ;
14
16
import java .util .Optional ;
15
17
import java .util .Set ;
@@ -35,6 +37,7 @@ public final class ControllerReader {
35
37
private final List <ExecutableElement > interfaceMethods ;
36
38
private final List <String > roles ;
37
39
private final List <MethodReader > methods = new ArrayList <>();
40
+ private final Set <String > seenMethods = new HashSet <>();
38
41
private final Set <String > staticImportTypes = new TreeSet <>();
39
42
private final Set <String > importTypes = new TreeSet <>();
40
43
private final List <OpenAPIResponsePrism > apiResponses ;
@@ -54,7 +57,7 @@ public final class ControllerReader {
54
57
55
58
public ControllerReader (TypeElement beanType ) {
56
59
this .beanType = beanType ;
57
- this .interfaces = initInterfaces ();
60
+ this .interfaces = initInterfaces (beanType );
58
61
this .interfaceMethods = initInterfaceMethods ();
59
62
this .roles = buildRoles ();
60
63
if (isOpenApiAvailable ()) {
@@ -115,9 +118,9 @@ void addImports(boolean withSingleton) {
115
118
}
116
119
}
117
120
118
- private List <TypeElement > initInterfaces () {
121
+ private List <TypeElement > initInterfaces (TypeElement element ) {
119
122
final List <TypeElement > superInterfaces = new ArrayList <>();
120
- for (final TypeMirror anInterface : beanType .getInterfaces ()) {
123
+ for (final TypeMirror anInterface : element .getInterfaces ()) {
121
124
final var ifaceElement = asElement (anInterface );
122
125
final var controller = ControllerPrism .getInstanceOn (ifaceElement );
123
126
if (controller != null && !controller .value ().isBlank ()
@@ -224,7 +227,9 @@ public void read(boolean withSingleton) {
224
227
readSuper (beanType );
225
228
226
229
if (platform ().getClass ().getSimpleName ().contains ("Client" )) {
227
- readInterfaces ();
230
+ for (final var superInterface : interfaces ) {
231
+ readInterfaces (superInterface );
232
+ }
228
233
}
229
234
deriveIncludeValidation ();
230
235
addImports (withSingleton );
@@ -273,12 +278,17 @@ private void readSuper(TypeElement beanType) {
273
278
}
274
279
}
275
280
276
- /** Read methods from interfaces taking into account generics. */
277
- private void readInterfaces () {
278
- for (final var superInterfaces : interfaces ) {
279
- for (final var element : ElementFilter .methodsIn (superInterfaces .getEnclosedElements ())) {
280
- readMethod (element , (DeclaredType ) superInterfaces .asType ());
281
- }
281
+ /**
282
+ * Read methods from interfaces taking into account generics.
283
+ *
284
+ * @param interfaceElement
285
+ */
286
+ private void readInterfaces (TypeElement interfaceElement ) {
287
+ for (final var element : ElementFilter .methodsIn (interfaceElement .getEnclosedElements ())) {
288
+ readMethod (element , (DeclaredType ) interfaceElement .asType ());
289
+ }
290
+ for (final var element : initInterfaces (interfaceElement )) {
291
+ readInterfaces (element );
282
292
}
283
293
}
284
294
@@ -293,7 +303,7 @@ private void readMethod(ExecutableElement method, DeclaredType declaredType) {
293
303
actualExecutable = (ExecutableType ) asMemberOf (declaredType , method );
294
304
}
295
305
final MethodReader methodReader = new MethodReader (this , method , actualExecutable );
296
- if (methodReader .isWebMethod ()) {
306
+ if (methodReader .isWebMethod () && seenMethods . add ( method . toString ()) ) {
297
307
methodReader .read ();
298
308
methods .add (methodReader );
299
309
}
0 commit comments