View Javadoc
1   package org.codehaus.plexus.compiler;
2   
3   /**
4    * The MIT License
5    *
6    * Copyright (c) 2004, The Codehaus
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   */
26  import java.io.File;
27  import java.util.AbstractMap;
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.HashSet;
32  import java.util.LinkedHashMap;
33  import java.util.LinkedList;
34  import java.util.List;
35  import java.util.Map;
36  import java.util.Set;
37  
38  import org.codehaus.plexus.util.StringUtils;
39  
40  /**
41   * @author jdcasey
42   */
43  public class CompilerConfiguration {
44      private String outputLocation;
45  
46      private List<String> classpathEntries = new LinkedList<>();
47  
48      private List<String> modulepathEntries = new LinkedList<>();
49  
50      // ----------------------------------------------------------------------
51      // Source Files
52      // ----------------------------------------------------------------------
53  
54      private Set<File> sourceFiles = new HashSet<>();
55  
56      private List<String> sourceLocations = new LinkedList<>();
57  
58      private Set<String> includes = new HashSet<>();
59  
60      private Set<String> excludes = new HashSet<>();
61  
62      // ----------------------------------------------------------------------
63      // Compiler Settings
64      // ----------------------------------------------------------------------
65  
66      private boolean debug;
67  
68      private String debugLevel;
69  
70      private boolean showWarnings = true;
71  
72      private String warnings;
73  
74      private boolean showLint;
75  
76      /**
77       * -Werror argument as supported since Java 1.7
78       */
79      private boolean failOnWarning;
80  
81      private boolean showDeprecation;
82  
83      private String sourceVersion;
84  
85      private String targetVersion;
86  
87      /**
88       * value of -release parameter in java 9+
89       */
90      private String releaseVersion;
91  
92      private String sourceEncoding;
93  
94      /**
95       * value of --module-version parameter in java 9+
96       */
97      private String moduleVersion;
98  
99      private Collection<Map.Entry<String, String>> customCompilerArguments = new ArrayList<>();
100 
101     private boolean fork;
102 
103     private boolean optimize;
104 
105     private String meminitial;
106 
107     private String maxmem;
108 
109     private String executable;
110 
111     private File workingDirectory;
112 
113     private String compilerVersion;
114 
115     private boolean verbose = false;
116 
117     /**
118      * @since 2.8.2
119      */
120     private boolean parameters;
121 
122     /**
123      * A build temporary directory, eg target/.
124      * <p/>
125      * Used by the compiler implementation to put temporary files.
126      */
127     private File buildDirectory;
128 
129     /**
130      * Used to control the name of the output file when compiling a set of
131      * sources to a single file.
132      */
133     private String outputFileName;
134 
135     /**
136      * in jdk 1.6+, used to hold value of the -s path parameter.
137      */
138     private File generatedSourcesDirectory;
139 
140     /**
141      * value of the -proc parameter in jdk 1.6+
142      */
143     private String proc;
144 
145     /**
146      * -processor parameters in jdk 1.6+
147      */
148     private String[] annotationProcessors;
149 
150     /**
151      * -processorpath parameter in jdk 1.6+. If specified, annotation processors are only searched in the processor
152      * path. Otherwise they are searched in the classpath.
153      */
154     private List<String> processorPathEntries;
155 
156     /**
157      * --processor-module-path parameter in jdk 9+. If specified, annotation processors are only searched in the processor
158      * path. Otherwise they are searched in the modulepath.
159      */
160     private List<String> processorModulePathEntries;
161 
162     /**
163      * default value {@link CompilerReuseStrategy#ReuseCreated}
164      *
165      * @since 1.9
166      */
167     private CompilerReuseStrategy compilerReuseStrategy = CompilerReuseStrategy.ReuseCreated;
168 
169     /**
170      * force usage of old JavacCompiler even if javax.tools is detected
171      * @since 2.0
172      */
173     private boolean forceJavacCompilerUse = false;
174 
175     /**
176      * force a different of the debug file containing the forked command run (such javac.sh)
177      * @since 2.9.1
178      */
179     private String debugFileName;
180 
181     /**
182      * configure <code>--enable-preview</code> of java compiler
183      */
184     private boolean enablePreview;
185 
186     /** value of <code>-implicit:</code> of java compiler */
187     private String implicitOption;
188 
189     // ----------------------------------------------------------------------
190     //
191     // ----------------------------------------------------------------------
192 
193     public void setOutputLocation(String outputLocation) {
194         this.outputLocation = outputLocation;
195     }
196 
197     public String getOutputLocation() {
198         return outputLocation;
199     }
200 
201     // ----------------------------------------------------------------------
202     // Class path
203     // ----------------------------------------------------------------------
204 
205     public void addClasspathEntry(String classpathEntry) {
206         classpathEntries.add(classpathEntry);
207     }
208 
209     public void setClasspathEntries(List<String> classpathEntries) {
210         if (classpathEntries == null) {
211             this.classpathEntries = Collections.emptyList();
212         } else {
213             this.classpathEntries = new LinkedList<>(classpathEntries);
214         }
215     }
216 
217     public List<String> getClasspathEntries() {
218         return Collections.unmodifiableList(classpathEntries);
219     }
220 
221     // ----------------------------------------------------------------------
222     // Module path
223     // ----------------------------------------------------------------------
224 
225     public void addModulepathEntry(String modulepathEntry) {
226         modulepathEntries.add(modulepathEntry);
227     }
228 
229     public void setModulepathEntries(List<String> modulepathEntries) {
230         if (modulepathEntries == null) {
231             this.modulepathEntries = Collections.emptyList();
232         } else {
233             this.modulepathEntries = new LinkedList<>(modulepathEntries);
234         }
235     }
236 
237     public List<String> getModulepathEntries() {
238         return Collections.unmodifiableList(modulepathEntries);
239     }
240 
241     // ----------------------------------------------------------------------
242     // Source files
243     // ----------------------------------------------------------------------
244 
245     public void setSourceFiles(Set<File> sourceFiles) {
246         if (sourceFiles == null) {
247             this.sourceFiles = Collections.emptySet();
248         } else {
249             this.sourceFiles = new HashSet<>(sourceFiles);
250         }
251     }
252 
253     public Set<File> getSourceFiles() {
254         return sourceFiles;
255     }
256 
257     public void addSourceLocation(String sourceLocation) {
258         sourceLocations.add(sourceLocation);
259     }
260 
261     public void setSourceLocations(List<String> sourceLocations) {
262         if (sourceLocations == null) {
263             this.sourceLocations = Collections.emptyList();
264         } else {
265             this.sourceLocations = new LinkedList<>(sourceLocations);
266         }
267     }
268 
269     public List<String> getSourceLocations() {
270         return Collections.unmodifiableList(sourceLocations);
271     }
272 
273     public void addInclude(String include) {
274         includes.add(include);
275     }
276 
277     public void setIncludes(Set<String> includes) {
278         if (includes == null) {
279             this.includes = Collections.emptySet();
280         } else {
281             this.includes = new HashSet<>(includes);
282         }
283     }
284 
285     public Set<String> getIncludes() {
286         return Collections.unmodifiableSet(includes);
287     }
288 
289     public void addExclude(String exclude) {
290         excludes.add(exclude);
291     }
292 
293     public void setExcludes(Set<String> excludes) {
294         if (excludes == null) {
295             this.excludes = Collections.emptySet();
296         } else {
297             this.excludes = new HashSet<>(excludes);
298         }
299     }
300 
301     public Set<String> getExcludes() {
302         return Collections.unmodifiableSet(excludes);
303     }
304 
305     // ----------------------------------------------------------------------
306     // Compiler Settings
307     // ----------------------------------------------------------------------
308 
309     public void setDebug(boolean debug) {
310         this.debug = debug;
311     }
312 
313     public boolean isDebug() {
314         return debug;
315     }
316 
317     public void setDebugLevel(String debugLevel) {
318         this.debugLevel = debugLevel;
319     }
320 
321     public String getDebugLevel() {
322         return debugLevel;
323     }
324 
325     public void setWarnings(String warnings) {
326         this.warnings = warnings;
327     }
328 
329     public boolean isShowWarnings() {
330         return showWarnings;
331     }
332 
333     public void setShowWarnings(boolean showWarnings) {
334         this.showWarnings = showWarnings;
335     }
336 
337     public boolean isShowDeprecation() {
338         return showDeprecation;
339     }
340 
341     public String getWarnings() {
342         return warnings;
343     }
344 
345     public void setShowLint(boolean showLint) {
346         this.showLint = showLint;
347     }
348 
349     public boolean isShowLint() {
350         return this.showLint;
351     }
352 
353     public void setShowDeprecation(boolean showDeprecation) {
354         this.showDeprecation = showDeprecation;
355     }
356 
357     public boolean isFailOnWarning() {
358         return failOnWarning;
359     }
360 
361     public void setFailOnWarning(boolean failOnWarnings) {
362         this.failOnWarning = failOnWarnings;
363     }
364 
365     public String getSourceVersion() {
366         return sourceVersion;
367     }
368 
369     public void setSourceVersion(String sourceVersion) {
370         this.sourceVersion = sourceVersion;
371     }
372 
373     public String getTargetVersion() {
374         return targetVersion;
375     }
376 
377     public void setTargetVersion(String targetVersion) {
378         this.targetVersion = targetVersion;
379     }
380 
381     public String getReleaseVersion() {
382         return releaseVersion;
383     }
384 
385     public void setReleaseVersion(String releaseVersion) {
386         this.releaseVersion = releaseVersion;
387     }
388 
389     public String getSourceEncoding() {
390         return sourceEncoding;
391     }
392 
393     public void setSourceEncoding(String sourceEncoding) {
394         this.sourceEncoding = sourceEncoding;
395     }
396 
397     public String getModuleVersion() {
398         return moduleVersion;
399     }
400 
401     public void setModuleVersion(String moduleVersion) {
402         this.moduleVersion = moduleVersion;
403     }
404 
405     public void addCompilerCustomArgument(String customArgument, String value) {
406         customCompilerArguments.add(new AbstractMap.SimpleImmutableEntry<>(customArgument, value));
407     }
408 
409     /**
410      * Get all unique argument keys and their value. In case of duplicate keys, last one added wins.
411      *
412      * @return
413      * @see CompilerConfiguration#getCustomCompilerArgumentsEntries()
414      */
415     public Map<String, String> getCustomCompilerArgumentsAsMap() {
416         LinkedHashMap<String, String> arguments = new LinkedHashMap<>(customCompilerArguments.size());
417         for (Map.Entry<String, String> entry : customCompilerArguments) {
418             arguments.put(entry.getKey(), entry.getValue());
419         }
420         return arguments;
421     }
422 
423     public void setCustomCompilerArgumentsAsMap(Map<String, String> customCompilerArguments) {
424         this.customCompilerArguments = new ArrayList<>();
425         if (customCompilerArguments != null) {
426             this.customCompilerArguments.addAll(customCompilerArguments.entrySet());
427         }
428     }
429 
430     /**
431      * In case argument keys are not unique, this will return all entries
432      *
433      * @return
434      */
435     public Collection<Map.Entry<String, String>> getCustomCompilerArgumentsEntries() {
436         return customCompilerArguments;
437     }
438 
439     public boolean isFork() {
440         return fork;
441     }
442 
443     public void setFork(boolean fork) {
444         this.fork = fork;
445     }
446 
447     public String getMeminitial() {
448         return meminitial;
449     }
450 
451     public void setMeminitial(String meminitial) {
452         this.meminitial = meminitial;
453     }
454 
455     public String getMaxmem() {
456         return maxmem;
457     }
458 
459     public void setMaxmem(String maxmem) {
460         this.maxmem = maxmem;
461     }
462 
463     public String getExecutable() {
464         return executable;
465     }
466 
467     public void setExecutable(String executable) {
468         this.executable = executable;
469     }
470 
471     public File getWorkingDirectory() {
472         return workingDirectory;
473     }
474 
475     public void setWorkingDirectory(File workingDirectory) {
476         this.workingDirectory = workingDirectory;
477     }
478 
479     public File getBuildDirectory() {
480         return buildDirectory;
481     }
482 
483     public void setBuildDirectory(File buildDirectory) {
484         this.buildDirectory = buildDirectory;
485     }
486 
487     public String getOutputFileName() {
488         return outputFileName;
489     }
490 
491     public void setOutputFileName(String outputFileName) {
492         this.outputFileName = outputFileName;
493     }
494 
495     public boolean isOptimize() {
496         return optimize;
497     }
498 
499     public void setOptimize(boolean optimize) {
500         this.optimize = optimize;
501     }
502 
503     /**
504      * @deprecated Don't use any longer because this is just the configured version which does not necessarily match the version
505      * of the actually executed compiler binary
506      */
507     @Deprecated
508     public String getCompilerVersion() {
509         return compilerVersion;
510     }
511 
512     /**
513      * @deprecated Don't use any longer because this is just the configured version which does not necessarily match the version
514      * of the actually executed compiler binary
515      */
516     @Deprecated
517     public void setCompilerVersion(String compilerVersion) {
518         this.compilerVersion = compilerVersion;
519     }
520 
521     public boolean isVerbose() {
522         return verbose;
523     }
524 
525     public void setVerbose(boolean verbose) {
526         this.verbose = verbose;
527     }
528 
529     public boolean isParameters() {
530         return parameters;
531     }
532 
533     public void setParameters(boolean parameters) {
534         this.parameters = parameters;
535     }
536 
537     public boolean isEnablePreview() {
538         return enablePreview;
539     }
540 
541     public void setEnablePreview(boolean enablePreview) {
542         this.enablePreview = enablePreview;
543     }
544 
545     public void setProc(String proc) {
546         this.proc = proc;
547     }
548 
549     public void setGeneratedSourcesDirectory(File generatedSourcesDirectory) {
550         this.generatedSourcesDirectory = generatedSourcesDirectory;
551     }
552 
553     public File getGeneratedSourcesDirectory() {
554         return generatedSourcesDirectory;
555     }
556 
557     public String getProc() {
558         return proc;
559     }
560 
561     public void setAnnotationProcessors(String[] annotationProcessors) {
562         this.annotationProcessors = annotationProcessors;
563     }
564 
565     public String[] getAnnotationProcessors() {
566         return annotationProcessors;
567     }
568 
569     /**
570      * -processorpath parameter in jdk 1.6+. If specified, annotation processors are only searched in the processor
571      * path. Otherwise they are searched in the classpath.
572      *
573      * @param entry processor path entry to add
574      */
575     public void addProcessorPathEntry(String entry) {
576         if (processorPathEntries == null) {
577             processorPathEntries = new LinkedList<>();
578         }
579 
580         processorPathEntries.add(entry);
581     }
582 
583     /**
584      * -processorpath parameter in jdk 1.6+. If specified, annotation processors are only searched in the processor
585      * path. Otherwise they are searched in the classpath.
586      *
587      * @return the processorPathEntries
588      */
589     public List<String> getProcessorPathEntries() {
590         return processorPathEntries;
591     }
592 
593     /**
594      * -processorpath parameter in jdk 1.6+. If specified, annotation processors are only searched in the processor
595      * path. Otherwise they are searched in the classpath.
596      *
597      * @param processorPathEntries the processorPathEntries to set
598      */
599     public void setProcessorPathEntries(List<String> processorPathEntries) {
600         this.processorPathEntries = processorPathEntries;
601     }
602 
603     public void addProcessorModulePathEntry(String entry) {
604         if (processorModulePathEntries == null) {
605             processorModulePathEntries = new LinkedList<>();
606         }
607 
608         processorModulePathEntries.add(entry);
609     }
610 
611     public List<String> getProcessorModulePathEntries() {
612         return processorModulePathEntries;
613     }
614 
615     public void setProcessorModulePathEntries(List<String> processorModulePathEntries) {
616         this.processorModulePathEntries = processorModulePathEntries;
617     }
618 
619     public CompilerReuseStrategy getCompilerReuseStrategy() {
620         return compilerReuseStrategy;
621     }
622 
623     public void setCompilerReuseStrategy(CompilerReuseStrategy compilerReuseStrategy) {
624         this.compilerReuseStrategy = compilerReuseStrategy;
625     }
626 
627     public String getDebugFileName() {
628         return debugFileName;
629     }
630 
631     public void setDebugFileName(String debugFileName) {
632         this.debugFileName = debugFileName;
633     }
634 
635     /**
636      * Re-use strategy of the compiler (implement for java only).
637      */
638     public enum CompilerReuseStrategy {
639         /**
640          * Always reuse the same.
641          * <b>Default strategy.</b>
642          */
643         ReuseSame("reuseSame"),
644         /**
645          * Re-create a new compiler for each use.
646          */
647         AlwaysNew("alwaysNew"),
648         /**
649          * Re-use already created compiler, create new one if non already exists.
650          * <b>Will mimic a kind of pool to prevent different threads use the same.</b>
651          */
652         ReuseCreated("reuseCreated");
653 
654         private String strategy;
655 
656         CompilerReuseStrategy(String strategy) {
657             this.strategy = strategy;
658         }
659 
660         public String getStrategy() {
661             return strategy;
662         }
663 
664         @Override
665         public String toString() {
666             return "CompilerReuseStrategy:" + this.strategy;
667         }
668     }
669 
670     public boolean isForceJavacCompilerUse() {
671         return forceJavacCompilerUse;
672     }
673 
674     public void setForceJavacCompilerUse(boolean forceJavacCompilerUse) {
675         this.forceJavacCompilerUse = forceJavacCompilerUse;
676     }
677 
678     public String getImplicitOption() {
679         return implicitOption;
680     }
681 
682     public void setImplicitOption(String implicitOption) {
683         this.implicitOption = implicitOption;
684     }
685 
686     public String describe() {
687         List<String> params = new ArrayList<>();
688 
689         if (isFork()) {
690             params.add("forked");
691         }
692 
693         // base options: debug, optimize, verbose, deprecation
694         if (isDebug()) {
695             if (StringUtils.isNotEmpty(getDebugLevel())) {
696                 params.add("debug:" + getDebugLevel());
697             } else {
698                 params.add("debug");
699             }
700         }
701         if (isVerbose()) {
702             params.add("verbose");
703         }
704         if (isShowDeprecation()) {
705             params.add("deprecation");
706         }
707         if (isParameters()) {
708             params.add("parameters");
709         }
710         if (isEnablePreview()) {
711             params.add("preview");
712         }
713 
714         // target bytecode options: release or target, module-path
715         if (!StringUtils.isEmpty(getReleaseVersion())) {
716             params.add("release " + getReleaseVersion());
717         } else if (!StringUtils.isEmpty(getTargetVersion())) {
718             params.add("target " + getTargetVersion());
719         }
720         if (getModulepathEntries() != null && !getModulepathEntries().isEmpty()) {
721             params.add("module-path");
722         }
723         return String.join(" ", params);
724     }
725 }