1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org_scala_tools_maven;
17
18 import java.io.File;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.List;
22
23 import org.codehaus.plexus.util.FileUtils;
24 import org_scala_tools_maven_executions.JavaMainCaller;
25 import org_scala_tools_maven_executions.MainHelper;
26
27
28
29
30 public abstract class ScalaCompilerSupport extends ScalaSourceMojoSupport {
31
32 public static final String ALL = "all";
33 public static final String MODIFIED_ONLY = "modified-only";
34
35
36
37
38 private boolean compileErrors;
39
40
41
42
43
44
45 protected long loopSleep = 2500;
46
47
48
49
50
51
52 private String recompileMode = ALL;
53
54
55
56
57
58
59
60
61 private boolean notifyCompilation = true;
62
63 abstract protected File getOutputDir() throws Exception;
64
65 abstract protected List<String> getClasspathElements() throws Exception;
66
67 private long _lastCompileAt = -1;
68
69 @Override
70 protected void doExecute() throws Exception {
71 File outputDir = normalize(getOutputDir());
72 if (!outputDir.exists()) {
73 outputDir.mkdirs();
74 }
75 if (getLog().isDebugEnabled()) {
76 for(File directory : getSourceDirectories()) {
77 getLog().debug(directory.getCanonicalPath());
78 }
79 }
80 int nbFiles = compile(getSourceDirectories(), outputDir, getClasspathElements(), false);
81 switch (nbFiles) {
82 case -1:
83 getLog().warn("No source files found.");
84 break;
85 case 0:
86 getLog().info("Nothing to compile - all classes are up to date");;
87 break;
88 default:
89 break;
90 }
91 }
92
93
94 protected int compile(File sourceDir, File outputDir, List<String> classpathElements, boolean compileInLoop) throws Exception, InterruptedException {
95
96 return compile(Arrays.asList(sourceDir), outputDir, classpathElements, compileInLoop);
97 }
98
99 protected int compile(List<File> sourceRootDirs, File outputDir, List<String> classpathElements, boolean compileInLoop) throws Exception, InterruptedException {
100 long t0 = System.currentTimeMillis();
101 if (_lastCompileAt < 0) {
102 _lastCompileAt = findLastSuccessfullCompilation(outputDir);
103 }
104
105 List<File> files = getFilesToCompile(sourceRootDirs, _lastCompileAt);
106
107 if (files == null) {
108 return -1;
109 }
110
111 if (files.size() < 1) {
112 return 0;
113 }
114 long t1 = System.currentTimeMillis();
115 getLog().info(String.format("Compiling %d source files to %s at %d", files.size(), outputDir.getAbsolutePath(), t1));
116 JavaMainCaller jcmd = getScalaCommand();
117 jcmd.redirectToLog();
118 jcmd.addArgs("-classpath", MainHelper.toMultiPath(classpathElements));
119 jcmd.addArgs("-d", outputDir.getAbsolutePath());
120
121 for (File f : files) {
122 jcmd.addArgs(f.getAbsolutePath());
123 }
124 if (jcmd.run(displayCmd, !compileInLoop)) {
125 setLastSuccessfullCompilation(outputDir, t1);
126 }
127 else {
128 compileErrors = true;
129 }
130 getLog().info(String.format("prepare-compile in %d s", (t1 - t0) / 1000));
131 getLog().info(String.format("compile in %d s", (System.currentTimeMillis() - t1) / 1000));
132 _lastCompileAt = t1;
133 return files.size();
134 }
135
136
137
138
139
140 protected boolean hasCompileErrors() {
141 return compileErrors;
142 }
143
144 protected void clearCompileErrors() {
145 compileErrors = false;
146 }
147
148 protected List<File> getFilesToCompile(List<File> sourceRootDirs, long lastSuccessfullCompileTime) throws Exception {
149 List<File> sourceFiles = findSourceWithFilters(sourceRootDirs);
150 if (sourceFiles.size() == 0) {
151 return null;
152 }
153
154
155
156
157
158
159 List<File> files = new ArrayList<File>(sourceFiles.size());
160 if (_lastCompileAt > 0 || (!ALL.equals(recompileMode) && (lastSuccessfullCompileTime > 0))) {
161 ArrayList<File> modifiedScalaFiles = new ArrayList<File>(sourceFiles.size());
162 ArrayList<File> modifiedJavaFiles = new ArrayList<File>(sourceFiles.size());
163 ArrayList<File> allJavaFiles = new ArrayList<File>(sourceFiles.size());
164 for (File f : sourceFiles) {
165 if (f.getName().endsWith(".java")) {
166 allJavaFiles.add(f);
167 }
168 if (f.lastModified() >= lastSuccessfullCompileTime) {
169 if (f.getName().endsWith(".java")) {
170 modifiedJavaFiles.add(f);
171 } else {
172 modifiedScalaFiles.add(f);
173 }
174 }
175 }
176 if ((modifiedScalaFiles.size() != 0) || (modifiedJavaFiles.size() != 0)) {
177 if ((modifiedScalaFiles.size() != 0) && MODIFIED_ONLY.equals(recompileMode)) {
178 files.addAll(allJavaFiles);
179 files.addAll(modifiedScalaFiles);
180 notifyCompilation(files);
181 } else {
182 files.addAll(sourceFiles);
183 notifyCompilation(sourceRootDirs);
184 }
185 }
186 } else {
187 files.addAll(sourceFiles);
188 notifyCompilation(sourceRootDirs);
189 }
190 return files;
191 }
192
193 private void notifyCompilation(List<File> files) throws Exception {
194 if (notifyCompilation) {
195 for (File f : files) {
196 getLog().info(String.format("%s:-1: info: compiling", f.getCanonicalPath()));
197 }
198 }
199 }
200
201 private long findLastSuccessfullCompilation(File outputDir) throws Exception {
202 long back = -1;
203 final File lastCompileAtFile = new File(outputDir + ".timestamp");
204 if (lastCompileAtFile.exists() && outputDir.exists() && (outputDir.list().length > 0)) {
205 back = lastCompileAtFile.lastModified();
206 }
207 return back;
208 }
209
210 private void setLastSuccessfullCompilation(File outputDir, long v) throws Exception {
211 final File lastCompileAtFile = new File(outputDir + ".timestamp");
212 if (lastCompileAtFile.exists()) {
213 } else {
214 FileUtils.fileWrite(lastCompileAtFile.getAbsolutePath(), ".");
215 }
216 lastCompileAtFile.setLastModified(v);
217 }
218 }