1
1
package io .avaje .http .generator .core ;
2
2
3
- import static io .avaje .http .generator .core .ProcessingContext .doc ;
4
- import static io .avaje .http .generator .core .ProcessingContext .elements ;
5
- import static io .avaje .http .generator .core .ProcessingContext .isOpenApiAvailable ;
6
- import static io .avaje .http .generator .core .ProcessingContext .logError ;
7
- import static io .avaje .http .generator .core .ProcessingContext .typeElement ;
3
+ import static io .avaje .http .generator .core .ProcessingContext .*;
8
4
import static java .util .stream .Collectors .toMap ;
9
5
10
6
import java .io .IOException ;
14
10
import java .util .HashSet ;
15
11
import java .util .Map ;
16
12
import java .util .Map .Entry ;
13
+ import java .util .Optional ;
17
14
import java .util .Set ;
18
15
19
16
import javax .annotation .processing .AbstractProcessor ;
22
19
import javax .annotation .processing .SupportedOptions ;
23
20
import javax .lang .model .SourceVersion ;
24
21
import javax .lang .model .element .Element ;
22
+ import javax .lang .model .element .ExecutableElement ;
23
+ import javax .lang .model .element .Modifier ;
25
24
import javax .lang .model .element .TypeElement ;
26
25
import javax .lang .model .util .ElementFilter ;
27
26
27
+ import io .avaje .http .generator .core .TypeMap .CustomHandler ;
28
28
import io .avaje .prism .GenerateAPContext ;
29
29
import io .avaje .prism .GenerateModuleInfoReader ;
30
30
@@ -54,7 +54,11 @@ public SourceVersion getSupportedSourceVersion() {
54
54
@ Override
55
55
public Set <String > getSupportedAnnotationTypes () {
56
56
return Set .of (
57
- PathPrism .PRISM_TYPE , ControllerPrism .PRISM_TYPE , OpenAPIDefinitionPrism .PRISM_TYPE );
57
+ PathPrism .PRISM_TYPE ,
58
+ ControllerPrism .PRISM_TYPE ,
59
+ OpenAPIDefinitionPrism .PRISM_TYPE ,
60
+ MappedParamPrism .PRISM_TYPE ,
61
+ MapImportPrism .PRISM_TYPE );
58
62
}
59
63
60
64
@ Override
@@ -65,7 +69,6 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
65
69
66
70
try {
67
71
var txtFilePath = APContext .getBuildResource (HTTP_CONTROLLERS_TXT );
68
-
69
72
if (txtFilePath .toFile ().exists ()) {
70
73
Files .lines (txtFilePath ).forEach (clientFQNs ::add );
71
74
}
@@ -75,8 +78,8 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
75
78
}
76
79
}
77
80
} catch (IOException e ) {
78
- e .printStackTrace ();
79
81
// not worth failing over
82
+ logWarn ("Error reading test controllers %s" , e );
80
83
}
81
84
}
82
85
@@ -88,6 +91,17 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
88
91
if (round .errorRaised ()) {
89
92
return false ;
90
93
}
94
+
95
+ for (final var type : ElementFilter .typesIn (getElements (round , MappedParamPrism .PRISM_TYPE ))) {
96
+ var prism = MappedParamPrism .getInstanceOn (type );
97
+ registerParamMapping (type , prism .factoryMethod ());
98
+ }
99
+
100
+ for (final var type : getElements (round , MapImportPrism .PRISM_TYPE )) {
101
+ var prism = MapImportPrism .getInstanceOn (type );
102
+ registerParamMapping (APContext .asTypeElement (prism .value ()), prism .factoryMethod ());
103
+ }
104
+
91
105
var pathElements = round .getElementsAnnotatedWith (typeElement (PathPrism .PRISM_TYPE ));
92
106
APContext .setProjectModuleElement (annotations , round );
93
107
if (contextPathString == null ) {
@@ -111,9 +125,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
111
125
readSecuritySchemes (round );
112
126
}
113
127
114
- for (final var controller :
115
- ElementFilter .typesIn (
116
- round .getElementsAnnotatedWith (typeElement (ControllerPrism .PRISM_TYPE )))) {
128
+ for (final var controller : ElementFilter .typesIn (round .getElementsAnnotatedWith (typeElement (ControllerPrism .PRISM_TYPE )))) {
117
129
writeAdapter (controller );
118
130
}
119
131
@@ -136,9 +148,33 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
136
148
return false ;
137
149
}
138
150
151
+ private Set <? extends Element > getElements (RoundEnvironment round , String name ) {
152
+ return Optional .ofNullable (typeElement (name ))
153
+ .map (round ::getElementsAnnotatedWith )
154
+ .orElse (Set .of ());
155
+ }
156
+
157
+ private final void registerParamMapping (final TypeElement type , String factoryMethod ) {
158
+ if (factoryMethod .isBlank ()) {
159
+ Util .stringConstructor (type )
160
+ .ifPresentOrElse (
161
+ c -> TypeMap .add (new CustomHandler (UType .parse (type .asType ()), "" )),
162
+ () -> logError (type , "Missing constructor %s(String s)" ));
163
+
164
+ } else {
165
+ ElementFilter .methodsIn (type .getEnclosedElements ()).stream ()
166
+ .filter (m -> m .getSimpleName ().contentEquals (factoryMethod )
167
+ && m .getModifiers ().contains (Modifier .STATIC )
168
+ && Util .singleStringParam (m ))
169
+ .findAny ()
170
+ .ifPresentOrElse (
171
+ c -> TypeMap .add (new CustomHandler (UType .parse (type .asType ()), factoryMethod )),
172
+ () -> logError (type , "Missing static factory method %s(String s)" , factoryMethod ));
173
+ }
174
+ }
175
+
139
176
private void readOpenApiDefinition (RoundEnvironment round ) {
140
- for (final Element element :
141
- round .getElementsAnnotatedWith (typeElement (OpenAPIDefinitionPrism .PRISM_TYPE ))) {
177
+ for (final Element element : round .getElementsAnnotatedWith (typeElement (OpenAPIDefinitionPrism .PRISM_TYPE ))) {
142
178
doc ().readApiDefinition (element );
143
179
}
144
180
}
@@ -147,19 +183,16 @@ private void readTagDefinitions(RoundEnvironment round) {
147
183
for (final Element element : round .getElementsAnnotatedWith (typeElement (TagPrism .PRISM_TYPE ))) {
148
184
doc ().addTagDefinition (element );
149
185
}
150
- for (final Element element :
151
- round .getElementsAnnotatedWith (typeElement (TagsPrism .PRISM_TYPE ))) {
186
+ for (final Element element : round .getElementsAnnotatedWith (typeElement (TagsPrism .PRISM_TYPE ))) {
152
187
doc ().addTagsDefinition (element );
153
188
}
154
189
}
155
190
156
191
private void readSecuritySchemes (RoundEnvironment round ) {
157
- for (final Element element :
158
- round .getElementsAnnotatedWith (typeElement (SecuritySchemePrism .PRISM_TYPE ))) {
192
+ for (final Element element : round .getElementsAnnotatedWith (typeElement (SecuritySchemePrism .PRISM_TYPE ))) {
159
193
doc ().addSecurityScheme (element );
160
194
}
161
- for (final Element element :
162
- round .getElementsAnnotatedWith (typeElement (SecuritySchemesPrism .PRISM_TYPE ))) {
195
+ for (final Element element : round .getElementsAnnotatedWith (typeElement (SecuritySchemesPrism .PRISM_TYPE ))) {
163
196
doc ().addSecuritySchemes (element );
164
197
}
165
198
}
@@ -174,7 +207,6 @@ private void writeAdapter(TypeElement controller) {
174
207
final var reader = new ControllerReader (controller , contextPath );
175
208
reader .read (true );
176
209
try {
177
-
178
210
writeControllerAdapter (reader );
179
211
writeClientAdapter (reader );
180
212
@@ -184,7 +216,6 @@ private void writeAdapter(TypeElement controller) {
184
216
}
185
217
186
218
private void writeClientAdapter (ControllerReader reader ) {
187
-
188
219
try {
189
220
if (reader .beanType ().getInterfaces ().isEmpty ()
190
221
&& "java.lang.Object" .equals (reader .beanType ().getSuperclass ().toString ())
0 commit comments