88import javax .lang .model .element .ElementKind ;
99import javax .lang .model .element .ExecutableElement ;
1010import javax .lang .model .element .TypeElement ;
11+ import javax .lang .model .type .TypeMirror ;
12+ import javax .lang .model .util .ElementFilter ;
13+ import java .lang .annotation .Annotation ;
1114import java .util .ArrayList ;
1215import java .util .List ;
1316import java .util .Set ;
@@ -24,6 +27,10 @@ class ControllerReader {
2427
2528 private final TypeElement beanType ;
2629
30+ private final List <Element > interfaces ;
31+
32+ private final List <ExecutableElement > interfaceMethods ;
33+
2734 private final List <String > roles ;
2835
2936 private final List <MethodReader > methods = new ArrayList <>();
@@ -42,27 +49,85 @@ class ControllerReader {
4249 ControllerReader (TypeElement beanType , ProcessingContext ctx ) {
4350 this .beanType = beanType ;
4451 this .ctx = ctx ;
52+ this .interfaces = initInterfaces ();
53+ this .interfaceMethods = initInterfaceMethods ();
4554 this .roles = Util .findRoles (beanType );
46- this .produces = produces (beanType );
4755 if (ctx .isGeneratedAvailable ()) {
4856 importTypes .add (Constants .GENERATED );
4957 }
5058 if (ctx .isOpenApiAvailable ()) {
51- docHidden = isDocHidden ( beanType );
59+ docHidden = initDocHidden ( );
5260 }
5361 importTypes .add (Constants .SINGLETON );
5462 importTypes .add (Constants .API_BUILDER );
5563 importTypes .add (Constants .IMPORT_CONTROLLER );
5664 importTypes .add (beanType .getQualifiedName ().toString ());
65+
66+ this .produces = initProduces ();
67+ }
68+
69+ private List <Element > initInterfaces () {
70+
71+ List <Element > interfaces = new ArrayList <>();
72+
73+ for (TypeMirror anInterface : beanType .getInterfaces ()) {
74+ final Element ifaceElement = ctx .asElement (anInterface );
75+ if (ifaceElement .getAnnotation (Path .class ) != null ) {
76+ interfaces .add (ifaceElement );
77+ }
78+ }
79+ return interfaces ;
80+ }
81+
82+ private List <ExecutableElement > initInterfaceMethods () {
83+
84+ List <ExecutableElement > ifaceMethods = new ArrayList <>();
85+ for (Element anInterface : interfaces ) {
86+ ifaceMethods .addAll (ElementFilter .methodsIn (anInterface .getEnclosedElements ()));
87+ }
88+ return ifaceMethods ;
89+ }
90+
91+ <A extends Annotation > A findAnnotation (Class <A > type ) {
92+ A annotation = beanType .getAnnotation (type );
93+ if (annotation != null ) {
94+ return annotation ;
95+ }
96+ for (Element anInterface : interfaces ) {
97+ annotation = anInterface .getAnnotation (type );
98+ if (annotation != null ) {
99+ return annotation ;
100+ }
101+ }
102+ return null ;
103+ }
104+
105+ <A extends Annotation > A findMethodAnnotation (Class <A > type , ExecutableElement element ) {
106+
107+ for (ExecutableElement interfaceMethod : interfaceMethods ) {
108+ if (matchMethod (interfaceMethod , element )) {
109+ final A annotation = interfaceMethod .getAnnotation (type );
110+ if (annotation != null ) {
111+ ctx .logDebug ("found interface method annotation : " + annotation + " 2:" + interfaceMethod );
112+ return annotation ;
113+ }
114+ }
115+ }
116+
117+ return null ;
118+ }
119+
120+ private boolean matchMethod (ExecutableElement interfaceMethod , ExecutableElement element ) {
121+ return interfaceMethod .toString ().equals (element .toString ());
57122 }
58123
59- private String produces ( TypeElement beanType ) {
60- final Produces produces = beanType . getAnnotation (Produces .class );
124+ private String initProduces ( ) {
125+ final Produces produces = findAnnotation (Produces .class );
61126 return (produces == null ) ? null : produces .value ();
62127 }
63128
64- private boolean isDocHidden ( TypeElement beanType ) {
65- return beanType . getAnnotation (Hidden .class ) != null ;
129+ private boolean initDocHidden ( ) {
130+ return findAnnotation (Hidden .class ) != null ;
66131 }
67132
68133 String getProduces () {
@@ -110,7 +175,7 @@ List<MethodReader> getMethods() {
110175 }
111176
112177 String getPath () {
113- Path path = beanType . getAnnotation (Path .class );
178+ Path path = findAnnotation (Path .class );
114179 if (path == null ) {
115180 return null ;
116181 }
0 commit comments