1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.compiler.stubs;
20
21 import javax.annotation.processing.Processor;
22 import javax.lang.model.SourceVersion;
23 import javax.tools.DiagnosticListener;
24 import javax.tools.FileObject;
25 import javax.tools.JavaCompiler;
26 import javax.tools.JavaFileManager;
27 import javax.tools.JavaFileObject;
28 import javax.tools.SimpleJavaFileObject;
29 import javax.tools.StandardJavaFileManager;
30 import javax.tools.StandardLocation;
31
32 import java.io.File;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.io.OutputStream;
36 import java.io.UncheckedIOException;
37 import java.io.Writer;
38 import java.nio.charset.Charset;
39 import java.util.ArrayList;
40 import java.util.Arrays;
41 import java.util.Iterator;
42 import java.util.List;
43 import java.util.Locale;
44 import java.util.Set;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class CompilerStub implements JavaCompiler, StandardJavaFileManager {
61
62
63
64
65
66
67 public static final String COMPILER_ID = "maven-compiler-stub";
68
69
70
71
72
73
74 public static final String OUTPUT_FILE = "compiled.class";
75
76
77
78
79
80
81 private File outputDir;
82
83
84
85
86
87
88 private static final ThreadLocal<Iterable<String>> ARGUMENTS = new ThreadLocal<>();
89
90
91
92
93 public CompilerStub() {}
94
95
96
97
98 @Override
99 public String name() {
100 return COMPILER_ID;
101 }
102
103
104
105
106
107 @Override
108 public Set<SourceVersion> getSourceVersions() {
109 return Set.of(SourceVersion.RELEASE_17);
110 }
111
112
113
114
115
116
117 @Override
118 public int isSupportedOption(String option) {
119 if (option.startsWith("-my&")) {
120 return 0;
121 }
122 switch (option) {
123 case "-Xlint":
124 return 0;
125 default:
126 return 1;
127 }
128 }
129
130
131
132
133 @Override
134 public StandardJavaFileManager getStandardFileManager(
135 DiagnosticListener<? super JavaFileObject> diagnosticListener, Locale locale, Charset charset) {
136 return this;
137 }
138
139
140
141
142
143 @Override
144 public boolean isSameFile(FileObject a, FileObject b) {
145 return a.equals(b);
146 }
147
148
149
150
151
152 private static final class UnknownFile extends SimpleJavaFileObject {
153 UnknownFile(final File file) {
154 super(file.toURI(), JavaFileObject.Kind.OTHER);
155 }
156
157 UnknownFile(final String name) {
158 this(new File(name));
159 }
160 }
161
162
163
164
165 @Override
166 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
167 var objects = new ArrayList<JavaFileObject>();
168 files.forEach(UnknownFile::new);
169 return objects;
170 }
171
172
173
174
175 @Override
176 public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
177 return getJavaFileObjectsFromFiles(Arrays.asList(files));
178 }
179
180
181
182
183 @Override
184 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
185 var objects = new ArrayList<JavaFileObject>();
186 names.forEach(UnknownFile::new);
187 return objects;
188 }
189
190
191
192
193 @Override
194 public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
195 return getJavaFileObjectsFromStrings(Arrays.asList(names));
196 }
197
198
199
200
201 @Override
202 public boolean hasLocation(Location location) {
203 return location == StandardLocation.CLASS_OUTPUT;
204 }
205
206
207
208
209
210 @Override
211 public void setLocation(Location location, Iterable<? extends File> files) {
212 if (location == StandardLocation.CLASS_OUTPUT) {
213 outputDir = null;
214 Iterator<? extends File> it = files.iterator();
215 if (it.hasNext()) {
216 outputDir = it.next();
217 if (it.hasNext()) {
218 throw new IllegalArgumentException("This simple stub accepts a maximum of one output directory.");
219 }
220 }
221 }
222 }
223
224
225
226
227 @Override
228 public Iterable<? extends File> getLocation(Location location) {
229 if (location == StandardLocation.CLASS_OUTPUT && outputDir != null) {
230 return Set.of(outputDir);
231 }
232 return Set.of();
233 }
234
235
236
237
238 @Override
239 public ClassLoader getClassLoader(Location location) {
240 return Thread.currentThread().getContextClassLoader();
241 }
242
243
244
245
246 @Override
247 public Iterable<JavaFileObject> list(
248 Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) {
249 return Set.of();
250 }
251
252
253
254
255 @Override
256 public String inferBinaryName(Location location, JavaFileObject file) {
257 return OUTPUT_FILE;
258 }
259
260
261
262
263 @Override
264 public boolean handleOption(String current, Iterator<String> remaining) {
265 return false;
266 }
267
268
269
270
271 @Override
272 public JavaFileObject getJavaFileForInput(Location location, String className, JavaFileObject.Kind kind) {
273 return null;
274 }
275
276
277
278
279 @Override
280 public JavaFileObject getJavaFileForOutput(
281 Location location, String className, JavaFileObject.Kind kind, FileObject sibling) {
282 return null;
283 }
284
285
286
287
288 @Override
289 public FileObject getFileForInput(Location location, String packageName, String relativeName) {
290 return null;
291 }
292
293
294
295
296 @Override
297 public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) {
298 return null;
299 }
300
301
302
303
304 @Override
305 public CompilationTask getTask(
306 Writer out,
307 JavaFileManager fileManager,
308 DiagnosticListener<? super JavaFileObject> diagnosticListener,
309 Iterable<String> options,
310 Iterable<String> classes,
311 Iterable<? extends JavaFileObject> compilationUnits) {
312
313 ARGUMENTS.set(options);
314 return new CompilationTask() {
315 @Override
316 public void addModules(Iterable<String> moduleNames) {}
317
318 @Override
319 public void setProcessors(Iterable<? extends Processor> processors) {}
320
321 @Override
322 public void setLocale(Locale locale) {}
323
324
325
326
327
328
329 @Override
330 public Boolean call() {
331 return run(null, null, null, (String[]) null) == 0;
332 }
333 };
334 }
335
336
337
338
339
340
341 @Override
342 public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
343 try {
344 outputDir.mkdirs();
345 File outputFile = new File(outputDir, OUTPUT_FILE);
346 outputFile.createNewFile();
347 } catch (IOException e) {
348 throw new UncheckedIOException("An exception occurred while creating output file.", e);
349 }
350 return 0;
351 }
352
353
354
355
356 public static List<String> getOptions() {
357 var options = new ArrayList<String>();
358 Iterable<String> args = ARGUMENTS.get();
359 if (args != null) {
360 args.forEach(options::add);
361 }
362 return options;
363 }
364
365
366
367
368 @Override
369 public void flush() {}
370
371
372
373
374 @Override
375 public void close() {}
376 }