1818import javax .tools .JavaFileObject ;
1919import java .io .IOException ;
2020import java .io .PrintWriter ;
21+ import java .util .ArrayList ;
22+ import java .util .List ;
2123import java .util .Set ;
2224
2325@ SupportedAnnotationTypes (
@@ -32,40 +34,36 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
3234 = roundEnv .getElementsAnnotatedWith (annotation );
3335 annotatedElements .stream ().filter (element -> element instanceof Symbol .ClassSymbol )
3436 .map (e -> (Symbol .ClassSymbol ) e )
35- .forEach (controllerClassSymbol -> generateDoneableClass ( controllerClassSymbol ) );
37+ .forEach (this :: generateDoneableClass );
3638 }
3739 return false ;
3840 }
3941
4042 private void generateDoneableClass (Symbol .ClassSymbol controllerClassSymbol ) {
4143 try {
42- // TODO: the resourceType retrieval logic is currently very fragile, done for testing purposes and need to be improved to cover all possible conditions
43- final Type controllerType = controllerClassSymbol
44- .getInterfaces ()
45- .stream ()
46- .filter (i -> i .toString ()
47- .startsWith (ResourceController .class .getCanonicalName ())
48- )
49- .findFirst ()
50- .orElseThrow (() -> new Exception ("ResourceController is not implemented by " + controllerClassSymbol .toString ()));
44+ final TypeMirror resourceType = findResourceType (controllerClassSymbol );
45+ Symbol .ClassSymbol customerResourceSymbol = (Symbol .ClassSymbol ) processingEnv
46+ .getElementUtils ()
47+ .getTypeElement (resourceType .toString ());
5148
52- final TypeMirror resourceType = controllerType .getTypeArguments ().get (0 );
53- Symbol .ClassSymbol customerResourceSymbol = (Symbol .ClassSymbol ) processingEnv .getElementUtils ().getTypeElement (resourceType .toString ());
5449 JavaFileObject builderFile = processingEnv .getFiler ()
5550 .createSourceFile (customerResourceSymbol .className () + "Doneable" );
51+
5652 try (PrintWriter out = new PrintWriter (builderFile .openWriter ())) {
5753 final MethodSpec constructor = MethodSpec .constructorBuilder ()
5854 .addModifiers (Modifier .PUBLIC )
5955 .addParameter (TypeName .get (resourceType ), "resource" )
6056 .addParameter (Function .class , "function" )
6157 .addStatement ("super(resource,function)" )
6258 .build ();
59+
6360 final TypeSpec typeSpec = TypeSpec .classBuilder (customerResourceSymbol .name + "Doneable" )
6461 .addAnnotation (RegisterForReflection .class )
6562 .superclass (ParameterizedTypeName .get (ClassName .get (CustomResourceDoneable .class ), TypeName .get (resourceType )))
6663 .addModifiers (Modifier .PUBLIC )
6764 .addMethod (constructor )
6865 .build ();
66+
6967 JavaFile file = JavaFile .builder (customerResourceSymbol .packge ().fullname .toString (), typeSpec )
7068 .build ();
7169 file .writeTo (out );
@@ -76,4 +74,29 @@ private void generateDoneableClass(Symbol.ClassSymbol controllerClassSymbol) {
7674 ex .printStackTrace ();
7775 }
7876 }
77+
78+ private TypeMirror findResourceType (Symbol .ClassSymbol controllerClassSymbol ) throws Exception {
79+ final Type controllerType = collectAllInterfaces (controllerClassSymbol )
80+ .stream ()
81+ .filter (i -> i .toString ()
82+ .startsWith (ResourceController .class .getCanonicalName ())
83+ )
84+ .findFirst ()
85+ .orElseThrow (() -> new Exception ("ResourceController is not implemented by " + controllerClassSymbol .toString ()));
86+
87+ final TypeMirror resourceType = controllerType .getTypeArguments ().get (0 );
88+ return resourceType ;
89+ }
90+
91+ private List <Type > collectAllInterfaces (Symbol .ClassSymbol classSymbol ) {
92+ List <Type > interfaces = new ArrayList <>(classSymbol .getInterfaces ());
93+ Symbol .ClassSymbol superclass = (Symbol .ClassSymbol ) processingEnv .getTypeUtils ().asElement (classSymbol .getSuperclass ());
94+
95+ while (superclass != null ) {
96+ interfaces .addAll (superclass .getInterfaces ());
97+ superclass = (Symbol .ClassSymbol ) processingEnv .getTypeUtils ().asElement (superclass .getSuperclass ());
98+ }
99+
100+ return interfaces ;
101+ }
79102}
0 commit comments