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