1 package org.apache.maven.plugin.dependency;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.BufferedWriter;
24 import java.io.File;
25 import java.io.FileReader;
26 import java.io.FileWriter;
27 import java.io.IOException;
28 import java.io.Writer;
29 import java.util.ArrayList;
30 import java.util.Comparator;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Set;
34 import java.util.regex.Matcher;
35 import java.util.regex.Pattern;
36
37 import org.apache.maven.artifact.Artifact;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugin.dependency.utils.DependencyUtil;
40 import org.apache.maven.project.MavenProjectHelper;
41 import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
42 import org.codehaus.plexus.util.IOUtil;
43 import org.codehaus.plexus.util.StringUtils;
44
45
46
47
48
49
50
51
52
53
54
55 public class BuildClasspathMojo
56 extends AbstractDependencyFilterMojo
57 implements Comparator<Artifact>
58 {
59
60
61
62
63
64
65
66 private boolean stripVersion = false;
67
68
69
70
71
72
73
74 private String prefix;
75
76
77
78
79
80
81
82
83 private File cpFile;
84
85
86
87
88
89 private File outputFile;
90
91
92
93
94
95
96 private boolean regenerateFile;
97
98
99
100
101
102
103
104
105
106 private String fileSeparator;
107
108
109
110
111
112
113
114
115
116
117 private String pathSeparator;
118
119
120
121
122
123
124
125
126 private String localRepoProperty;
127
128
129
130
131
132
133
134 boolean attach;
135
136
137
138
139
140
141
142 boolean outputFilterFile;
143
144
145
146
147
148
149
150 private MavenProjectHelper projectHelper;
151
152 boolean isFileSepSet = true;
153
154 boolean isPathSepSet = true;
155
156
157
158
159
160
161
162
163 public void execute()
164 throws MojoExecutionException
165 {
166
167 if ( cpFile != null )
168 {
169 getLog().warn( "The parameter cpFile is deprecated. Use outputFile instead." );
170 this.outputFile = cpFile;
171 }
172
173
174 isFileSepSet = StringUtils.isNotEmpty( fileSeparator );
175 isPathSepSet = StringUtils.isNotEmpty( pathSeparator );
176
177
178 if ( attach && StringUtils.isEmpty( localRepoProperty ) )
179 {
180 localRepoProperty = "${M2_REPO}";
181 }
182
183 Set<Artifact> artifacts = getResolvedDependencies( true );
184
185 if ( artifacts == null || artifacts.isEmpty() )
186 {
187 getLog().info( "No dependencies found." );
188 }
189
190 List<Artifact> artList = new ArrayList<Artifact>( artifacts );
191
192 StringBuffer sb = new StringBuffer();
193 Iterator<Artifact> i = artList.iterator();
194
195 if ( i.hasNext() )
196 {
197 appendArtifactPath( i.next(), sb );
198
199 while ( i.hasNext() )
200 {
201 sb.append( isPathSepSet ? this.pathSeparator : File.pathSeparator );
202 appendArtifactPath( (Artifact) i.next(), sb );
203 }
204 }
205
206 String cpString = sb.toString();
207
208
209
210 if ( isFileSepSet )
211 {
212
213 final String pattern = Pattern.quote( File.separator );
214 final String replacement = Matcher.quoteReplacement( fileSeparator );
215 cpString = cpString.replaceAll( pattern, replacement );
216 }
217
218
219 if ( outputFilterFile )
220 {
221 cpString = "classpath=" + cpString;
222 }
223
224 if ( outputFile == null )
225 {
226 getLog().info( "Dependencies classpath:\n" + cpString );
227 }
228 else
229 {
230 if ( regenerateFile || !isUpdToDate( cpString ) )
231 {
232 storeClasspathFile( cpString, outputFile );
233 }
234 else
235 {
236 this.getLog().info( "Skipped writing classpath file '" + outputFile + "'. No changes found." );
237 }
238 }
239 if ( attach )
240 {
241 attachFile( cpString );
242 }
243 }
244
245 protected void attachFile( String cpString )
246 throws MojoExecutionException
247 {
248 File attachedFile = new File( project.getBuild().getDirectory(), "classpath" );
249 storeClasspathFile( cpString, attachedFile );
250
251 projectHelper.attachArtifact( project, attachedFile, "classpath" );
252 }
253
254
255
256
257
258
259
260 protected void appendArtifactPath( Artifact art, StringBuffer sb )
261 {
262 if ( prefix == null )
263 {
264 String file = art.getFile().getPath();
265
266 if ( StringUtils.isNotEmpty( localRepoProperty ) )
267 {
268 file = StringUtils.replace( file, getLocal().getBasedir(), localRepoProperty );
269 }
270 sb.append( file );
271 }
272 else
273 {
274
275 sb.append( prefix );
276 sb.append( File.separator );
277 sb.append( DependencyUtil.getFormattedFileName( art, this.stripVersion, this.prependGroupId) );
278 }
279 }
280
281
282
283
284
285
286
287
288 private boolean isUpdToDate( String cpString )
289 {
290 try
291 {
292 String oldCp = readClasspathFile();
293 return ( cpString == oldCp || ( cpString != null && cpString.equals( oldCp ) ) );
294 }
295 catch ( Exception ex )
296 {
297 this.getLog().warn( "Error while reading old classpath file '" + outputFile + "' for up-to-date check: " + ex );
298
299 return false;
300 }
301 }
302
303
304
305
306
307
308
309 private void storeClasspathFile( String cpString, File out )
310 throws MojoExecutionException
311 {
312
313 out.getParentFile().mkdirs();
314
315 Writer w = null;
316 try
317 {
318 w = new BufferedWriter( new FileWriter( out ) );
319 w.write( cpString );
320 getLog().info( "Wrote classpath file '" + out + "'." );
321 }
322 catch ( IOException ex )
323 {
324 throw new MojoExecutionException( "Error while writting to classpath file '" + out + "': "
325 + ex.toString(), ex );
326 }
327 finally
328 {
329 IOUtil.close( w );
330 }
331 }
332
333
334
335
336
337
338
339
340 protected String readClasspathFile()
341 throws IOException
342 {
343 if ( outputFile == null )
344 {
345 throw new IllegalArgumentException(
346 "The outputFile parameter cannot be null if the file is intended to be read." );
347 }
348
349 if ( !outputFile.isFile() )
350 {
351 return null;
352 }
353 StringBuffer sb = new StringBuffer();
354 BufferedReader r = null;
355
356 try
357 {
358 r = new BufferedReader( new FileReader( outputFile ) );
359 String l;
360 while ( ( l = r.readLine() ) != null )
361 {
362 sb.append( l );
363 }
364
365 return sb.toString();
366 }
367 finally
368 {
369 IOUtil.close( r );
370 }
371 }
372
373
374
375
376
377
378
379
380
381
382 public int compare( Artifact art1, Artifact art2 )
383 {
384 if ( art1 == art2 )
385 {
386 return 0;
387 }
388 else if ( art1 == null )
389 {
390 return -1;
391 }
392 else if ( art2 == null )
393 {
394 return +1;
395 }
396
397 String s1 = art1.getGroupId() + art1.getArtifactId() + art1.getVersion();
398 String s2 = art2.getGroupId() + art2.getArtifactId() + art2.getVersion();
399
400 return s1.compareTo( s2 );
401 }
402
403 protected ArtifactsFilter getMarkedArtifactFilter()
404 {
405 return null;
406 }
407
408
409
410
411 public File getCpFile()
412 {
413 return this.outputFile;
414 }
415
416
417
418
419 public void setCpFile( File theCpFile )
420 {
421 this.outputFile = theCpFile;
422 }
423
424
425
426
427 public String getFileSeparator()
428 {
429 return this.fileSeparator;
430 }
431
432
433
434
435 public void setFileSeparator( String theFileSeparator )
436 {
437 this.fileSeparator = theFileSeparator;
438 }
439
440
441
442
443 public String getPathSeparator()
444 {
445 return this.pathSeparator;
446 }
447
448
449
450
451 public void setPathSeparator( String thePathSeparator )
452 {
453 this.pathSeparator = thePathSeparator;
454 }
455
456
457
458
459 public String getPrefix()
460 {
461 return this.prefix;
462 }
463
464
465
466
467 public void setPrefix( String thePrefix )
468 {
469 this.prefix = thePrefix;
470 }
471
472
473
474
475 public boolean isRegenerateFile()
476 {
477 return this.regenerateFile;
478 }
479
480
481
482
483 public void setRegenerateFile( boolean theRegenerateFile )
484 {
485 this.regenerateFile = theRegenerateFile;
486 }
487
488
489
490
491 public boolean isStripVersion()
492 {
493 return this.stripVersion;
494 }
495
496
497
498
499 public void setStripVersion( boolean theStripVersion )
500 {
501 this.stripVersion = theStripVersion;
502 }
503
504 public String getLocalRepoProperty()
505 {
506 return localRepoProperty;
507 }
508
509 public void setLocalRepoProperty( String localRepoProperty )
510 {
511 this.localRepoProperty = localRepoProperty;
512 }
513
514 public boolean isFileSepSet()
515 {
516 return isFileSepSet;
517 }
518
519 public void setFileSepSet( boolean isFileSepSet )
520 {
521 this.isFileSepSet = isFileSepSet;
522 }
523
524 public boolean isPathSepSet()
525 {
526 return isPathSepSet;
527 }
528
529 public void setPathSepSet( boolean isPathSepSet )
530 {
531 this.isPathSepSet = isPathSepSet;
532 }
533 }