18
18
import javax .tools .JavaFileObject ;
19
19
import java .io .IOException ;
20
20
import java .io .PrintWriter ;
21
+ import java .util .ArrayList ;
22
+ import java .util .List ;
21
23
import java .util .Set ;
22
24
23
25
@ SupportedAnnotationTypes (
@@ -32,40 +34,36 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
32
34
= roundEnv .getElementsAnnotatedWith (annotation );
33
35
annotatedElements .stream ().filter (element -> element instanceof Symbol .ClassSymbol )
34
36
.map (e -> (Symbol .ClassSymbol ) e )
35
- .forEach (controllerClassSymbol -> generateDoneableClass ( controllerClassSymbol ) );
37
+ .forEach (this :: generateDoneableClass );
36
38
}
37
39
return false ;
38
40
}
39
41
40
42
private void generateDoneableClass (Symbol .ClassSymbol controllerClassSymbol ) {
41
43
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 ());
51
48
52
- final TypeMirror resourceType = controllerType .getTypeArguments ().get (0 );
53
- Symbol .ClassSymbol customerResourceSymbol = (Symbol .ClassSymbol ) processingEnv .getElementUtils ().getTypeElement (resourceType .toString ());
54
49
JavaFileObject builderFile = processingEnv .getFiler ()
55
50
.createSourceFile (customerResourceSymbol .className () + "Doneable" );
51
+
56
52
try (PrintWriter out = new PrintWriter (builderFile .openWriter ())) {
57
53
final MethodSpec constructor = MethodSpec .constructorBuilder ()
58
54
.addModifiers (Modifier .PUBLIC )
59
55
.addParameter (TypeName .get (resourceType ), "resource" )
60
56
.addParameter (Function .class , "function" )
61
57
.addStatement ("super(resource,function)" )
62
58
.build ();
59
+
63
60
final TypeSpec typeSpec = TypeSpec .classBuilder (customerResourceSymbol .name + "Doneable" )
64
61
.addAnnotation (RegisterForReflection .class )
65
62
.superclass (ParameterizedTypeName .get (ClassName .get (CustomResourceDoneable .class ), TypeName .get (resourceType )))
66
63
.addModifiers (Modifier .PUBLIC )
67
64
.addMethod (constructor )
68
65
.build ();
66
+
69
67
JavaFile file = JavaFile .builder (customerResourceSymbol .packge ().fullname .toString (), typeSpec )
70
68
.build ();
71
69
file .writeTo (out );
@@ -76,4 +74,29 @@ private void generateDoneableClass(Symbol.ClassSymbol controllerClassSymbol) {
76
74
ex .printStackTrace ();
77
75
}
78
76
}
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
+ }
79
102
}
0 commit comments