1 package org.apache.maven.plugins.source;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.List;
27
28 import org.apache.maven.archiver.MavenArchiveConfiguration;
29 import org.apache.maven.archiver.MavenArchiver;
30 import org.apache.maven.artifact.DependencyResolutionRequiredException;
31 import org.apache.maven.execution.MavenSession;
32 import org.apache.maven.model.Resource;
33 import org.apache.maven.plugin.AbstractMojo;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugins.annotations.Component;
36 import org.apache.maven.plugins.annotations.Parameter;
37 import org.apache.maven.project.MavenProject;
38 import org.apache.maven.project.MavenProjectHelper;
39 import org.codehaus.plexus.archiver.Archiver;
40 import org.codehaus.plexus.archiver.ArchiverException;
41 import org.codehaus.plexus.archiver.jar.JarArchiver;
42 import org.codehaus.plexus.archiver.jar.ManifestException;
43 import org.codehaus.plexus.util.FileUtils;
44
45
46
47
48
49
50 public abstract class AbstractSourceJarMojo
51 extends AbstractMojo
52 {
53 private static final String[] DEFAULT_INCLUDES = new String[] { "**/*" };
54
55 private static final String[] DEFAULT_EXCLUDES = new String[] {};
56
57
58
59
60
61
62
63 @Parameter
64 private String[] includes;
65
66
67
68
69
70
71
72 @Parameter
73 private String[] excludes;
74
75
76
77
78
79
80
81 @Parameter( property = "maven.source.useDefaultExcludes", defaultValue = "true" )
82 private boolean useDefaultExcludes;
83
84
85
86
87 @Parameter( defaultValue = "${project}", readonly = true, required = true )
88 private MavenProject project;
89
90
91
92
93 @Component( role = Archiver.class, hint = "jar" )
94 private JarArchiver jarArchiver;
95
96
97
98
99
100
101
102
103
104
105 @Parameter
106 private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
107
108
109
110
111
112
113
114
115 @Parameter( defaultValue = "${project.build.outputDirectory}/META-INF/MANIFEST.MF", readonly = false, required = true )
116
117 private File defaultManifestFile;
118
119
120
121
122
123
124 @Parameter( property = "maven.source.useDefaultManifestFile", defaultValue = "false" )
125 private boolean useDefaultManifestFile;
126
127
128
129
130 @Parameter( property = "maven.source.attach", defaultValue = "true" )
131 private boolean attach;
132
133
134
135
136
137
138
139 @Parameter( property = "maven.source.excludeResources", defaultValue = "false" )
140 protected boolean excludeResources;
141
142
143
144
145
146
147 @Parameter( property = "maven.source.includePom", defaultValue = "false" )
148 protected boolean includePom;
149
150
151
152
153 @Component
154 private MavenProjectHelper projectHelper;
155
156
157
158
159 @Parameter( defaultValue = "${project.build.directory}" )
160 protected File outputDirectory;
161
162
163
164
165
166 @Parameter( defaultValue = "${project.build.finalName}" )
167 protected String finalName;
168
169
170
171
172 @Parameter( defaultValue = "${reactorProjects}", readonly = true )
173 protected List<MavenProject> reactorProjects;
174
175
176
177
178
179
180
181 @Parameter( property = "maven.source.forceCreation", defaultValue = "false" )
182 private boolean forceCreation;
183
184
185
186
187
188
189
190 @Parameter( property = "maven.source.skip", defaultValue = "false" )
191 private boolean skipSource;
192
193
194
195
196 @Parameter( defaultValue = "${session}", readonly = true, required = true )
197 private MavenSession session;
198
199
200
201
202
203
204
205
206 public void execute()
207 throws MojoExecutionException
208 {
209 if ( skipSource )
210 {
211 getLog().info( "Skipping source per configuration." );
212 return;
213 }
214
215 packageSources( project );
216 }
217
218
219
220
221
222
223
224
225 protected abstract String getClassifier();
226
227
228
229
230
231
232 protected abstract List<String> getSources( MavenProject p )
233 throws MojoExecutionException;
234
235
236
237
238
239
240 protected abstract List<Resource> getResources( MavenProject p )
241 throws MojoExecutionException;
242
243
244
245
246
247 protected void packageSources( MavenProject p )
248 throws MojoExecutionException
249 {
250 if ( !"pom".equals( p.getPackaging() ) )
251 {
252 packageSources( Arrays.asList( p ) );
253 }
254 }
255
256
257
258
259
260 protected void packageSources( List<MavenProject> theProjects )
261 throws MojoExecutionException
262 {
263 if ( project.getArtifact().getClassifier() != null )
264 {
265 getLog().warn( "NOT adding sources to artifacts with classifier as Maven only supports one classifier "
266 + "per artifact. Current artifact [" + project.getArtifact().getId() + "] has a ["
267 + project.getArtifact().getClassifier() + "] classifier." );
268
269 return;
270 }
271
272 MavenArchiver archiver = createArchiver();
273
274 for ( MavenProject pItem : theProjects )
275 {
276 MavenProject subProject = getProject( pItem );
277
278 if ( "pom".equals( subProject.getPackaging() ) )
279 {
280 continue;
281 }
282
283 archiveProjectContent( subProject, archiver.getArchiver() );
284 }
285
286 if ( archiver.getArchiver().getResources().hasNext() || forceCreation )
287 {
288
289 if ( useDefaultManifestFile && defaultManifestFile.exists() && archive.getManifestFile() == null )
290 {
291 getLog().info( "Adding existing MANIFEST to archive. Found under: " + defaultManifestFile.getPath() );
292 archive.setManifestFile( defaultManifestFile );
293 }
294
295 File outputFile = new File( outputDirectory, finalName + "-" + getClassifier() + getExtension() );
296
297 try
298 {
299 archiver.setOutputFile( outputFile );
300 archive.setForced( forceCreation );
301
302 archiver.createArchive( session, project, archive );
303 }
304 catch ( IOException e )
305 {
306 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
307 }
308 catch ( ArchiverException e )
309 {
310 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
311 }
312 catch ( DependencyResolutionRequiredException e )
313 {
314 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
315 }
316 catch ( ManifestException e )
317 {
318 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
319 }
320
321 if ( attach )
322 {
323 projectHelper.attachArtifact( project, getType(), getClassifier(), outputFile );
324 }
325 else
326 {
327 getLog().info( "NOT adding java-sources to attached artifacts list." );
328 }
329 }
330 else
331 {
332 getLog().info( "No sources in project. Archive not created." );
333 }
334 }
335
336
337
338
339
340
341 protected void archiveProjectContent( MavenProject p, Archiver archiver )
342 throws MojoExecutionException
343 {
344 if ( includePom )
345 {
346 try
347 {
348 archiver.addFile( p.getFile(), p.getFile().getName() );
349 }
350 catch ( ArchiverException e )
351 {
352 throw new MojoExecutionException( "Error adding POM file to target jar file.", e );
353 }
354 }
355
356 for ( String s : getSources( p ) )
357 {
358
359 File sourceDirectory = new File( s );
360
361 if ( sourceDirectory.exists() )
362 {
363 addDirectory( archiver, sourceDirectory, getCombinedIncludes( null ), getCombinedExcludes( null ) );
364 }
365 }
366
367
368 for ( Resource resource : getResources( p ) )
369 {
370
371 File sourceDirectory = new File( resource.getDirectory() );
372
373 if ( !sourceDirectory.exists() )
374 {
375 continue;
376 }
377
378 List<String> resourceIncludes = resource.getIncludes();
379
380 String[] combinedIncludes = getCombinedIncludes( resourceIncludes );
381
382 List<String> resourceExcludes = resource.getExcludes();
383
384 String[] combinedExcludes = getCombinedExcludes( resourceExcludes );
385
386 String targetPath = resource.getTargetPath();
387 if ( targetPath != null )
388 {
389 if ( !targetPath.trim().endsWith( "/" ) )
390 {
391 targetPath += "/";
392 }
393 addDirectory( archiver, sourceDirectory, targetPath, combinedIncludes, combinedExcludes );
394 }
395 else
396 {
397 addDirectory( archiver, sourceDirectory, combinedIncludes, combinedExcludes );
398 }
399 }
400 }
401
402
403
404
405
406 protected MavenArchiver createArchiver()
407 throws MojoExecutionException
408 {
409 MavenArchiver archiver = new MavenArchiver();
410 archiver.setArchiver( jarArchiver );
411
412 if ( project.getBuild() != null )
413 {
414 List<Resource> resources = project.getBuild().getResources();
415
416 for ( Resource r : resources )
417 {
418
419 if ( r.getDirectory().endsWith( "maven-shared-archive-resources" ) )
420 {
421 addDirectory( archiver.getArchiver(), new File( r.getDirectory() ), getCombinedIncludes( null ),
422 getCombinedExcludes( null ) );
423 }
424 }
425 }
426
427 return archiver;
428 }
429
430
431
432
433
434
435
436
437 protected void addDirectory( Archiver archiver, File sourceDirectory, String[] pIncludes, String[] pExcludes )
438 throws MojoExecutionException
439 {
440 try
441 {
442
443 archiver.addDirectory( sourceDirectory, pIncludes, pExcludes );
444 }
445 catch ( ArchiverException e )
446 {
447 throw new MojoExecutionException( "Error adding directory to source archive.", e );
448 }
449 }
450
451
452
453
454
455
456
457
458
459 protected void addDirectory( Archiver archiver, File sourceDirectory, String prefix, String[] pIncludes,
460 String[] pExcludes )
461 throws MojoExecutionException
462 {
463 try
464 {
465 archiver.addDirectory( sourceDirectory, prefix, pIncludes, pExcludes );
466 }
467 catch ( ArchiverException e )
468 {
469 throw new MojoExecutionException( "Error adding directory to source archive.", e );
470 }
471 }
472
473
474
475
476 protected String getExtension()
477 {
478 return ".jar";
479 }
480
481
482
483
484
485 protected MavenProject getProject( MavenProject p )
486 {
487 if ( p.getExecutionProject() != null )
488 {
489 return p.getExecutionProject();
490 }
491
492 return p;
493 }
494
495
496
497
498 protected String getType()
499 {
500 return "java-source";
501 }
502
503
504
505
506
507
508
509
510 private String[] getCombinedIncludes( List<String> additionalIncludes )
511 {
512 List<String> combinedIncludes = new ArrayList<String>();
513
514 if ( includes != null && includes.length > 0 )
515 {
516 combinedIncludes.addAll( Arrays.asList( includes ) );
517 }
518
519 if ( additionalIncludes != null && additionalIncludes.size() > 0 )
520 {
521 combinedIncludes.addAll( additionalIncludes );
522 }
523
524
525 if ( combinedIncludes.size() == 0 )
526 {
527 combinedIncludes.addAll( Arrays.asList( DEFAULT_INCLUDES ) );
528 }
529
530 return combinedIncludes.toArray( new String[combinedIncludes.size()] );
531 }
532
533
534
535
536
537
538
539
540
541 private String[] getCombinedExcludes( List<String> additionalExcludes )
542 {
543 List<String> combinedExcludes = new ArrayList<String>();
544
545 if ( useDefaultExcludes )
546 {
547 combinedExcludes.addAll( FileUtils.getDefaultExcludesAsList() );
548 }
549
550 if ( excludes != null && excludes.length > 0 )
551 {
552 combinedExcludes.addAll( Arrays.asList( excludes ) );
553 }
554
555 if ( additionalExcludes != null && additionalExcludes.size() > 0 )
556 {
557 combinedExcludes.addAll( additionalExcludes );
558 }
559
560 if ( combinedExcludes.size() == 0 )
561 {
562 combinedExcludes.addAll( Arrays.asList( DEFAULT_EXCLUDES ) );
563 }
564
565 return combinedExcludes.toArray( new String[combinedExcludes.size()] );
566 }
567
568
569
570
571 protected MavenProject getProject()
572 {
573 return project;
574 }
575
576
577
578
579 protected void setProject( MavenProject project )
580 {
581 this.project = project;
582 }
583 }