@@ -12,23 +12,19 @@ public static void write(PrintWriter out, String packageName) {
12
12
+ packageName
13
13
+ ";\n "
14
14
+ "\n "
15
- + "import static java.util.stream.Collectors.joining;\n "
16
- + "import static java.util.stream.Collectors.toList;\n "
17
- + "\n "
18
- + "import java.io.BufferedReader;\n "
19
- + "import java.io.IOException;\n "
20
- + "import java.util.ArrayList;\n "
21
- + "import java.util.Arrays;\n "
22
- + "import java.util.HashSet;\n "
23
- + "import java.util.List;\n "
24
- + "import java.util.Set;\n "
15
+ + "import static java.util.stream.Collectors.*;\n "
16
+ + "\n "
17
+ + "import java.io.*;\n "
18
+ + "import java.net.URI;\n "
19
+ + "import java.util.*;\n "
25
20
+ "import java.util.regex.Matcher;\n "
26
21
+ "import java.util.regex.Pattern;\n "
27
22
+ "\n "
28
23
+ "import javax.annotation.processing.Generated;\n "
29
24
+ "import javax.lang.model.element.ModuleElement;\n "
30
25
+ "import javax.lang.model.element.ModuleElement.DirectiveKind;\n "
31
26
+ "import javax.lang.model.element.ModuleElement.RequiresDirective;\n "
27
+ + "import javax.tools.StandardLocation;\n "
32
28
+ "import javax.lang.model.element.PackageElement;\n "
33
29
+ "\n "
34
30
+ "/**\n "
@@ -58,6 +54,7 @@ public static void write(PrintWriter out, String packageName) {
58
54
+ " private final List<Exports> exports = new ArrayList<>();\n "
59
55
+ " private final List<Opens> opens = new ArrayList<>();\n "
60
56
+ " private final List<Provides> provides = new ArrayList<>();\n "
57
+ + " private final ModuleElement moduleElement;\n "
61
58
+ "\n "
62
59
+ " /**\n "
63
60
+ " * Parse a module-info and create a new instance\n "
@@ -77,7 +74,7 @@ public static void write(PrintWriter out, String packageName) {
77
74
+ " * @param moduleString a string containing the contents of the module-info.java\n "
78
75
+ " */\n "
79
76
+ " public ModuleInfoReader(ModuleElement moduleElement, CharSequence moduleString) {\n "
80
- + "\n "
77
+ + " this.moduleElement = moduleElement; \n "
81
78
+ " Matcher importMatcher = IMPORT_PATTERN.matcher(moduleString);\n "
82
79
+ " Matcher requiresMatcher = REQUIRES_PATTERN.matcher(moduleString);\n "
83
80
+ " Matcher providesMatcher = PROVIDES_PATTERN.matcher(moduleString);\n "
@@ -119,7 +116,7 @@ public static void write(PrintWriter out, String packageName) {
119
116
+ " }\n "
120
117
+ "\n "
121
118
+ " while (providesMatcher.find()) {\n "
122
- + " String providedInterface = resolveImport(imports,providesMatcher.group(1));\n "
119
+ + " String providedInterface = resolveImport(imports, providesMatcher.group(1));\n "
123
120
+ " String implementationClasses = providesMatcher.group(2);\n "
124
121
+ "\n "
125
122
+ " List<String> implementations =\n "
@@ -139,7 +136,8 @@ public static void write(PrintWriter out, String packageName) {
139
136
+ " return imports.stream()\n "
140
137
+ " .filter(s -> s.contains(providedInterface))\n "
141
138
+ " .findFirst()\n "
142
- + " .orElse(providedInterface).replaceAll(\" \\ \\ s\" , \" \" );\n "
139
+ + " .orElse(providedInterface)\n "
140
+ + " .replaceAll(\" \\ \\ s\" , \" \" );\n "
143
141
+ " }\n "
144
142
+ "\n "
145
143
+ " /**\n "
@@ -191,6 +189,82 @@ public static void write(PrintWriter out, String packageName) {
191
189
+ " return requires.stream().anyMatch(r -> hasNonStaticModule(name, r.getDependency(), seen));\n "
192
190
+ " }\n "
193
191
+ "\n "
192
+ + " private String replace$(String k) {\n "
193
+ + " return k.replace('$', '.');\n "
194
+ + " }\n "
195
+ + "\n "
196
+ + " /**\n "
197
+ + " * Checks whether the module-info has the defined provides directive and all their implementations\n "
198
+ + " * Will register an error message compilation\n "
199
+ + " *\n "
200
+ + " * @param providesType the provides directive to check\n "
201
+ + " * @param implementations the implementations to verify the presence of\n "
202
+ + " */\n "
203
+ + " public void validateServices(String providesType, Collection<String> implementations) {\n "
204
+ + " if (!buildPluginAvailable() || !moduleElement.isUnnamed()) {\n "
205
+ + " return;\n "
206
+ + " }\n "
207
+ + " var implSet = new TreeSet<>(implementations);\n "
208
+ + " try (final var file =\n "
209
+ + " APContext.filer()\n "
210
+ + " .getResource(StandardLocation.CLASS_OUTPUT, \" \" , \" META-INF/services/\" + providesType)\n "
211
+ + " .toUri()\n "
212
+ + " .toURL()\n "
213
+ + " .openStream();\n "
214
+ + " final var buffer = new BufferedReader(new InputStreamReader(file)); ) {\n "
215
+ + "\n "
216
+ + " String line;\n "
217
+ + " while ((line = buffer.readLine()) != null) {\n "
218
+ + " line.replaceAll(\" \\ \\ s\" , \" \" ).replace(\" ,\" , \" \\ n\" ).lines().forEach(implSet::add);\n "
219
+ + " }\n "
220
+ + " } catch (Exception e) {\n "
221
+ + " // not a critical error\n "
222
+ + " }\n "
223
+ + " final var missingImpls = implSet.stream().map(this::replace$).collect(toSet());\n "
224
+ + "\n "
225
+ + " provides()\n "
226
+ + " .forEach(\n "
227
+ + " p -> {\n "
228
+ + " final var contract = replace$(providesType);\n "
229
+ + " if (!providesType.equals(contract)) {\n "
230
+ + " return;\n "
231
+ + " }\n "
232
+ + " var impls = p.implementations();\n "
233
+ + " if (missingImpls.size() > impls.size()) {\n "
234
+ + " return;\n "
235
+ + " }\n "
236
+ + " impls.stream().map(this::replace$).forEach(missingImpls::remove);\n "
237
+ + " });\n "
238
+ + "\n "
239
+ + " if (!missingImpls.isEmpty()) {\n "
240
+ + " var message = implementations.stream().collect(joining(\" , \" ));\n "
241
+ + "\n "
242
+ + " APContext.logError(\" Missing `provides %s with %s;`\" , providesType, message);\n "
243
+ + " }\n "
244
+ + " }\n "
245
+ + "\n "
246
+ + " private static boolean buildPluginAvailable() {\n "
247
+ + " return resource(\" target/avaje-plugin-exists.txt\" , \" /target/classes\" )\n "
248
+ + " || resource(\" build/avaje-plugin-exists.txt\" , \" /build/classes/java/main\" );\n "
249
+ + " }\n "
250
+ + "\n "
251
+ + " private static boolean resource(String relativeName, String replace) {\n "
252
+ + " try (var inputStream =\n "
253
+ + " new URI(\n "
254
+ + " APContext.filer()\n "
255
+ + " .getResource(StandardLocation.CLASS_OUTPUT, \" \" , relativeName)\n "
256
+ + " .toUri()\n "
257
+ + " .toString()\n "
258
+ + " .replace(replace, \" \" ))\n "
259
+ + " .toURL()\n "
260
+ + " .openStream()) {\n "
261
+ + "\n "
262
+ + " return inputStream.available() > 0;\n "
263
+ + " } catch (Exception e) {\n "
264
+ + " return false;\n "
265
+ + " }\n "
266
+ + " }\n "
267
+ + "\n "
194
268
+ " /** The requires directives associated with this module */\n "
195
269
+ " public List<Requires> requires() {\n "
196
270
+ " return requires;\n "
@@ -349,6 +423,6 @@ public static void write(PrintWriter out, String packageName) {
349
423
+ " return targets;\n "
350
424
+ " }\n "
351
425
+ " }\n "
352
- + "}\n " );
426
+ + "}" );
353
427
}
354
428
}
0 commit comments