1 package org.codehaus.plexus.compiler;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import java.io.File;
27 import java.io.IOException;
28 import java.util.Collections;
29 import java.util.List;
30 import java.util.Set;
31 import java.util.TreeSet;
32
33 import org.codehaus.plexus.util.DirectoryScanner;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37
38
39
40
41
42 public abstract class AbstractCompiler implements Compiler {
43 private final Logger log = LoggerFactory.getLogger(getClass());
44
45 private final org.codehaus.plexus.logging.Logger plexusLogger;
46
47 protected static final String EOL = System.lineSeparator();
48
49 protected static final String PS = System.getProperty("path.separator");
50
51 private final CompilerOutputStyle compilerOutputStyle;
52
53 private final String inputFileEnding;
54
55 private final String outputFileEnding;
56
57 private final String outputFile;
58
59
60
61
62
63 protected AbstractCompiler(
64 CompilerOutputStyle compilerOutputStyle,
65 String inputFileEnding,
66 String outputFileEnding,
67 String outputFile) {
68 this.compilerOutputStyle = compilerOutputStyle;
69
70 this.inputFileEnding = inputFileEnding;
71
72 this.outputFileEnding = outputFileEnding;
73
74 this.outputFile = outputFile;
75
76 this.plexusLogger = new PlexusLoggerWrapper(log);
77 }
78
79
80
81
82
83 protected Logger getLog() {
84 return log;
85 }
86
87
88
89
90
91 @Deprecated
92 protected org.codehaus.plexus.logging.Logger getLogger() {
93 return plexusLogger;
94 }
95
96
97
98
99
100 public abstract String getCompilerId();
101
102 @Override
103 public CompilerResult performCompile(CompilerConfiguration configuration) throws CompilerException {
104 throw new CompilerNotImplementedException("The performCompile method has not been implemented.");
105 }
106
107 @Override
108 public CompilerOutputStyle getCompilerOutputStyle() {
109 return compilerOutputStyle;
110 }
111
112 @Override
113 public String getInputFileEnding(CompilerConfiguration configuration) throws CompilerException {
114 return inputFileEnding;
115 }
116
117 @Override
118 public String getOutputFileEnding(CompilerConfiguration configuration) throws CompilerException {
119 if (compilerOutputStyle != CompilerOutputStyle.ONE_OUTPUT_FILE_PER_INPUT_FILE) {
120 throw new RuntimeException("This compiler implementation doesn't have one output file per input file.");
121 }
122
123 return outputFileEnding;
124 }
125
126 @Override
127 public String getOutputFile(CompilerConfiguration configuration) throws CompilerException {
128 if (compilerOutputStyle != CompilerOutputStyle.ONE_OUTPUT_FILE_FOR_ALL_INPUT_FILES) {
129 throw new RuntimeException("This compiler implementation doesn't have one output file for all files.");
130 }
131
132 return outputFile;
133 }
134
135 @Override
136 public boolean canUpdateTarget(CompilerConfiguration configuration) throws CompilerException {
137 return true;
138 }
139
140
141
142
143
144 public static String getPathString(List<String> pathElements) {
145 StringBuilder sb = new StringBuilder();
146
147 for (String pathElement : pathElements) {
148 sb.append(pathElement).append(File.pathSeparator);
149 }
150
151 return sb.toString();
152 }
153
154 protected static Set<String> getSourceFilesForSourceRoot(CompilerConfiguration config, String sourceLocation) {
155
156 DirectoryScanner scanner = new DirectoryScanner();
157 scanner.setBasedir(sourceLocation);
158
159 if (!scanner.getBasedir().exists()) {
160 return Collections.emptySet();
161 }
162
163 Set<String> includes = config.getIncludes();
164
165 if (includes != null && !includes.isEmpty()) {
166 String[] inclStrs = includes.toArray(new String[0]);
167 scanner.setIncludes(inclStrs);
168 } else {
169 scanner.setIncludes(new String[] {"**/*.java"});
170 }
171
172 Set<String> excludes = config.getExcludes();
173
174 if (excludes != null && !excludes.isEmpty()) {
175 String[] exclStrs = excludes.toArray(new String[0]);
176 scanner.setExcludes(exclStrs);
177 }
178
179 scanner.scan();
180
181 String[] sourceDirectorySources = scanner.getIncludedFiles();
182
183 Set<String> sources = new TreeSet<>();
184
185 for (String sourceDirectorySource : sourceDirectorySources) {
186 File f = new File(sourceLocation, sourceDirectorySource);
187
188 sources.add(f.getPath());
189 }
190
191 return sources;
192 }
193
194 protected static String[] getSourceFiles(CompilerConfiguration config) {
195 Set<String> sources = new TreeSet<>();
196
197 Set<File> sourceFiles = config.getSourceFiles();
198
199 if (sourceFiles != null && !sourceFiles.isEmpty()) {
200 for (File sourceFile : sourceFiles) {
201 sources.add(sourceFile.getAbsolutePath());
202 }
203 } else {
204 for (String sourceLocation : config.getSourceLocations()) {
205 sources.addAll(getSourceFilesForSourceRoot(config, sourceLocation));
206 }
207 }
208
209 String[] result;
210
211 if (sources.isEmpty()) {
212 result = new String[0];
213 } else {
214 result = sources.toArray(new String[0]);
215 }
216
217 return result;
218 }
219
220 protected static String makeClassName(String fileName, String sourceDir) throws CompilerException {
221 File origFile = new File(fileName);
222
223 String canonical = null;
224
225 if (origFile.exists()) {
226 canonical = getCanonicalPath(origFile).replace('\\', '/');
227 }
228
229 if (sourceDir != null) {
230 String prefix = getCanonicalPath(new File(sourceDir)).replace('\\', '/');
231
232 if (canonical != null) {
233 if (canonical.startsWith(prefix)) {
234 String result = canonical.substring(prefix.length() + 1, canonical.length() - 5);
235
236 result = result.replace('/', '.');
237
238 return result;
239 }
240 } else {
241 File t = new File(sourceDir, fileName);
242
243 if (t.exists()) {
244 String str = getCanonicalPath(t).replace('\\', '/');
245
246 return str.substring(prefix.length() + 1, str.length() - 5).replace('/', '.');
247 }
248 }
249 }
250
251 if (fileName.endsWith(".java")) {
252 fileName = fileName.substring(0, fileName.length() - 5);
253 }
254
255 fileName = fileName.replace('\\', '.');
256
257 return fileName.replace('/', '.');
258 }
259
260 private static String getCanonicalPath(File origFile) throws CompilerException {
261 try {
262 return origFile.getCanonicalPath();
263 } catch (IOException e) {
264 throw new CompilerException(
265 "Error while getting the canonical path of '" + origFile.getAbsolutePath() + "'.", e);
266 }
267 }
268
269 protected void logCompiling(String[] sourceFiles, CompilerConfiguration config) {
270 if (log.isInfoEnabled()) {
271 log.info("Compiling "
272 + (sourceFiles == null
273 ? ""
274 : (sourceFiles.length + " source file" + (sourceFiles.length == 1 ? " " : "s ")))
275 + "with "
276 + getCompilerId() + " [" + config.describe() + "]" + " to "
277 + getRelativeWorkingDirectory(config));
278 }
279 }
280
281 private static String getRelativeWorkingDirectory(CompilerConfiguration config) {
282 String to;
283 if (config.getWorkingDirectory() == null) {
284 to = config.getOutputLocation();
285 } else {
286 try {
287 to = config.getWorkingDirectory()
288 .toPath()
289 .relativize(new File(config.getOutputLocation()).toPath())
290 .toString();
291 } catch (IllegalArgumentException e) {
292
293 to = config.getOutputLocation();
294 }
295 }
296 return to;
297 }
298 }