1 package org.apache.maven.shared.incremental;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.execution.MavenSession;
23 import org.apache.maven.plugin.MojoExecution;
24 import org.apache.maven.plugin.MojoExecutionException;
25 import org.apache.maven.project.MavenProject;
26 import org.apache.maven.shared.utils.io.DirectoryScanResult;
27 import org.apache.maven.shared.utils.io.DirectoryScanner;
28 import org.apache.maven.shared.utils.io.FileUtils;
29
30 import java.io.File;
31 import java.io.IOException;
32 import java.util.Set;
33
34
35
36
37 public class IncrementalBuildHelper
38 {
39
40
41
42 private static final String MAVEN_STATUS_ROOT = "maven-status";
43 public static final String CREATED_FILES_LST_FILENAME = "createdFiles.lst";
44 private static final String INPUT_FILES_LST_FILENAME = "inputFiles.lst";
45
46 private static final String[] EMPTY_ARRAY = new String[0];
47
48
49
50
51 private MojoExecution mojoExecution;
52
53
54
55
56 private MavenProject mavenProject;
57
58
59
60
61
62 private DirectoryScanner directoryScanner;
63
64
65
66
67
68 private String[] filesBeforeAction = new String[0];
69
70 public IncrementalBuildHelper( MojoExecution mojoExecution, MavenSession mavenSession )
71 {
72 this( mojoExecution, getMavenProject( mavenSession ) );
73 }
74
75 public IncrementalBuildHelper( MojoExecution mojoExecution, MavenProject mavenProject )
76 {
77 if ( mavenProject == null )
78 {
79 throw new IllegalArgumentException( "MavenProject must not be null!" );
80 }
81 if ( mojoExecution == null )
82 {
83 throw new IllegalArgumentException( "MojoExecution must not be null!" );
84 }
85
86 this.mavenProject = mavenProject;
87 this.mojoExecution = mojoExecution;
88 }
89
90
91
92
93 private static MavenProject getMavenProject( MavenSession mavenSession )
94 {
95 if ( mavenSession == null )
96 {
97 throw new IllegalArgumentException( "MavenSession must not be null!" );
98 }
99
100 return mavenSession.getCurrentProject();
101 }
102
103
104
105
106
107
108 public DirectoryScanner getDirectoryScanner()
109 {
110 if ( directoryScanner == null )
111 {
112 directoryScanner = new DirectoryScanner();
113 }
114
115 return directoryScanner;
116 }
117
118
119
120
121
122 public void setDirectoryScanner( DirectoryScanner directoryScanner )
123 {
124 this.directoryScanner = directoryScanner;
125 }
126
127
128
129
130
131
132 public File getMojoStatusDirectory()
133 throws MojoExecutionException
134 {
135 if ( mojoExecution == null )
136 {
137 throw new MojoExecutionException( "MojoExecution could not get resolved" );
138 }
139
140 File buildOutputDirectory = new File( mavenProject.getBuild().getDirectory() );
141
142
143
144
145 String mojoStatusPath = MAVEN_STATUS_ROOT + File.separator
146 + mojoExecution.getMojoDescriptor().getPluginDescriptor().getArtifactId() + File.separator
147 + mojoExecution.getMojoDescriptor().getGoal() + File.separator
148 + mojoExecution.getExecutionId();
149
150 File mojoStatusDir = new File( buildOutputDirectory, mojoStatusPath );
151
152 if ( !mojoStatusDir.exists() )
153 {
154 mojoStatusDir.mkdirs();
155 }
156
157 return mojoStatusDir;
158 }
159
160
161
162
163
164
165
166
167
168
169 public boolean inputFileTreeChanged( IncrementalBuildHelperRequest incrementalBuildHelperRequest )
170 throws MojoExecutionException
171 {
172 File mojoConfigBase = getMojoStatusDirectory();
173 File mojoConfigFile = new File( mojoConfigBase, INPUT_FILES_LST_FILENAME );
174
175 String[] oldInputFiles = new String[0];
176
177 if ( mojoConfigFile.exists() )
178 {
179 try
180 {
181 oldInputFiles = FileUtils.fileReadArray( mojoConfigFile );
182 }
183 catch( IOException e )
184 {
185 throw new MojoExecutionException( "Error reading old mojo status " + mojoConfigFile, e );
186 }
187 }
188
189 String[] inputFileNames = new String[ incrementalBuildHelperRequest.getInputFiles().size() ];
190 int i = 0;
191 for ( File inputFile : incrementalBuildHelperRequest.getInputFiles() )
192 {
193 inputFileNames[ i++ ] = inputFile.getAbsolutePath();
194 }
195
196 DirectoryScanResult dsr = DirectoryScanner.diffFiles( oldInputFiles, inputFileNames );
197
198 try
199 {
200 FileUtils.fileWriteArray( mojoConfigFile, inputFileNames );
201 }
202 catch( IOException e )
203 {
204 throw new MojoExecutionException( "Error while storing the mojo status", e );
205 }
206
207 return ( dsr.getFilesAdded().length > 0 || dsr.getFilesRemoved().length > 0 );
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221 public boolean inputFileTreeChanged( DirectoryScanner dirScanner )
222 throws MojoExecutionException
223 {
224 File mojoConfigBase = getMojoStatusDirectory();
225 File mojoConfigFile = new File( mojoConfigBase, INPUT_FILES_LST_FILENAME );
226
227 String[] oldInputFiles = new String[0];
228
229 if ( mojoConfigFile.exists() )
230 {
231 try
232 {
233 oldInputFiles = FileUtils.fileReadArray( mojoConfigFile );
234 }
235 catch( IOException e )
236 {
237 throw new MojoExecutionException( "Error reading old mojo status " + mojoConfigFile, e );
238 }
239 }
240
241 dirScanner.scan();
242
243 try
244 {
245
246 FileUtils.fileWriteArray( mojoConfigFile, dirScanner.getIncludedFiles() );
247 }
248 catch( IOException e )
249 {
250 throw new MojoExecutionException( "Error while storing new mojo status" + mojoConfigFile, e );
251 }
252
253 DirectoryScanResult dsr = dirScanner.diffIncludedFiles( oldInputFiles );
254
255 return ( dsr.getFilesAdded().length > 0 || dsr.getFilesRemoved().length > 0 );
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 public String[] beforeRebuildExecution( IncrementalBuildHelperRequest incrementalBuildHelperRequest )
278 throws MojoExecutionException
279 {
280 File mojoConfigBase = getMojoStatusDirectory();
281 File mojoConfigFile = new File( mojoConfigBase, CREATED_FILES_LST_FILENAME );
282
283 String[] oldFiles;
284
285 try
286 {
287 oldFiles = FileUtils.fileReadArray( mojoConfigFile );
288 for ( String oldFileName : oldFiles )
289 {
290 File oldFile = new File( incrementalBuildHelperRequest.getOutputDirectory(), oldFileName );
291 oldFile.delete();
292 }
293 }
294 catch( IOException e )
295 {
296 throw new MojoExecutionException( "Error reading old mojo status", e );
297 }
298
299
300 DirectoryScanner diffScanner = getDirectoryScanner();
301 diffScanner.setBasedir( incrementalBuildHelperRequest.getOutputDirectory() );
302 if ( incrementalBuildHelperRequest.getOutputDirectory().exists() )
303 {
304 diffScanner.scan();
305 filesBeforeAction = diffScanner.getIncludedFiles();
306 }
307
308 return oldFiles;
309 }
310
311
312
313
314
315
316
317
318
319
320
321 public void afterRebuildExecution( IncrementalBuildHelperRequest incrementalBuildHelperRequest )
322 throws MojoExecutionException
323 {
324 DirectoryScanner diffScanner = getDirectoryScanner();
325
326 diffScanner.scan();
327 DirectoryScanResult scanResult = diffScanner.diffIncludedFiles( filesBeforeAction );
328
329 File mojoConfigBase = getMojoStatusDirectory();
330 File mojoConfigFile = new File( mojoConfigBase, CREATED_FILES_LST_FILENAME );
331
332 try
333 {
334 FileUtils.fileWriteArray( mojoConfigFile, scanResult.getFilesAdded() );
335 }
336 catch ( IOException e )
337 {
338 throw new MojoExecutionException( "Error while storing the mojo status", e );
339 }
340
341
342
343 mojoConfigFile = new File( mojoConfigBase, INPUT_FILES_LST_FILENAME );
344 if ( !mojoConfigFile.exists() )
345 {
346 try
347 {
348 FileUtils.fileWriteArray( mojoConfigFile, toArrayOfPath( incrementalBuildHelperRequest.getInputFiles() ));
349 }
350 catch ( IOException e )
351 {
352 throw new MojoExecutionException( "Error while storing the mojo status", e );
353 }
354 }
355
356 }
357
358 private String[] toArrayOfPath( Set<File> files )
359 {
360 if (files == null || files.isEmpty())
361 {
362 return EMPTY_ARRAY;
363 }
364 String[] paths = new String[files.size()];
365
366 int i = 0;
367
368 for ( File file : files )
369 {
370 paths[i] = file.getPath();
371 i++;
372 }
373
374 return paths;
375 }
376 }