1 package org.apache.maven.plugins.assembly.mojos;
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.io.UncheckedIOException;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.List;
28 import java.util.Properties;
29
30 import org.apache.maven.archiver.MavenArchiveConfiguration;
31 import org.apache.maven.archiver.MavenArchiver;
32 import org.apache.maven.artifact.repository.ArtifactRepository;
33 import org.apache.maven.execution.MavenSession;
34 import org.apache.maven.plugin.AbstractMojo;
35 import org.apache.maven.plugin.MojoExecutionException;
36 import org.apache.maven.plugin.MojoFailureException;
37 import org.apache.maven.plugin.logging.Log;
38 import org.apache.maven.plugins.annotations.Component;
39 import org.apache.maven.plugins.annotations.Parameter;
40 import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
41 import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
42 import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
43 import org.apache.maven.plugins.assembly.archive.AssemblyArchiver;
44 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
45 import org.apache.maven.plugins.assembly.io.AssemblyReadException;
46 import org.apache.maven.plugins.assembly.io.AssemblyReader;
47 import org.apache.maven.plugins.assembly.model.Assembly;
48 import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
49 import org.apache.maven.plugins.assembly.utils.InterpolationConstants;
50 import org.apache.maven.project.MavenProject;
51 import org.apache.maven.project.MavenProjectHelper;
52 import org.apache.maven.shared.filtering.MavenReaderFilter;
53 import org.codehaus.plexus.configuration.PlexusConfiguration;
54 import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
55 import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
56 import org.codehaus.plexus.interpolation.fixed.PropertiesBasedValueSource;
57 import org.codehaus.plexus.util.cli.CommandLineUtils;
58
59
60
61
62
63 public abstract class AbstractAssemblyMojo extends AbstractMojo implements AssemblerConfigurationSource
64 {
65
66 protected FixedStringSearchInterpolator commandLinePropertiesInterpolator;
67
68 protected FixedStringSearchInterpolator envInterpolator;
69
70 protected FixedStringSearchInterpolator mainProjectInterpolator;
71
72 protected FixedStringSearchInterpolator rootInterpolator;
73
74
75
76
77
78
79 @Parameter( property = "assembly.appendAssemblyId", defaultValue = "true" )
80 boolean appendAssemblyId;
81
82
83
84
85 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
86 private String encoding;
87
88
89
90
91
92
93
94 @Parameter( property = "assembly.escapeString" )
95 private String escapeString;
96
97
98
99
100
101 @Parameter( property = "assembly.skipAssembly", defaultValue = "false" )
102 private boolean skipAssembly;
103
104
105
106
107 @Parameter( property = "assembly.dryRun", defaultValue = "false" )
108 private boolean dryRun;
109
110
111
112
113
114
115 @Parameter( defaultValue = "true" )
116 private boolean ignoreDirFormatExtensions;
117
118
119
120
121 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
122 private ArtifactRepository localRepository;
123
124
125
126
127 @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
128 private List<ArtifactRepository> remoteRepositories;
129
130
131
132
133 @Parameter( defaultValue = "${reactorProjects}", required = true, readonly = true )
134 private List<MavenProject> reactorProjects;
135
136
137
138
139 @Parameter( defaultValue = "${project.build.directory}", required = true )
140 private File outputDirectory;
141
142
143
144
145 @Parameter( defaultValue = "${project.build.finalName}", required = true, readonly = true )
146 private String finalName;
147
148
149
150
151 @Parameter( defaultValue = "${project.build.directory}/assembly/work", required = true )
152 private File workDirectory;
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 @Parameter
169 private List<String> formats;
170
171
172
173
174 @Parameter
175 private String[] descriptors;
176
177
178
179
180
181
182
183 @Parameter
184 private String[] descriptorRefs;
185
186
187
188
189 @Parameter
190 private File descriptorSourceDirectory;
191
192
193
194
195
196 @Parameter
197 private File archiveBaseDirectory;
198
199
200
201
202
203 @Parameter( property = "assembly.tarLongFileMode", defaultValue = "warn" )
204 private String tarLongFileMode;
205
206
207
208
209 @Parameter( defaultValue = "${project.basedir}", required = true, readonly = true )
210 private File basedir;
211
212
213
214
215 @Component
216 private MavenProjectHelper projectHelper;
217
218
219
220
221 @Component
222 private MavenReaderFilter mavenReaderFilter;
223
224
225
226
227 @Parameter( defaultValue = "${session}", readonly = true, required = true )
228 private MavenSession mavenSession;
229
230
231
232
233 @Parameter( defaultValue = "${project.build.directory}/archive-tmp", required = true, readonly = true )
234 private File tempRoot;
235
236
237
238
239 @Parameter( defaultValue = "${project.reporting.outputDirectory}", readonly = true )
240 private File siteDirectory;
241
242
243
244
245 @Parameter( property = "assembly.ignoreMissingDescriptor", defaultValue = "false" )
246 private boolean ignoreMissingDescriptor;
247
248
249
250
251
252
253 @Parameter
254 private MavenArchiveConfiguration archive;
255
256
257
258
259
260
261
262 @Parameter
263 private List<String> filters;
264
265
266
267
268
269
270 @Parameter
271 private Properties additionalProperties;
272
273
274
275
276
277
278
279 @Parameter( property = "assembly.includeProjectBuildFilters", defaultValue = "true" )
280 private boolean includeProjectBuildFilters;
281
282
283
284
285
286
287 @Parameter( property = "assembly.attach", defaultValue = "true" )
288 private boolean attach;
289
290
291
292
293
294
295
296 @Parameter( defaultValue = "true" )
297 private boolean recompressZippedFiles;
298
299
300
301
302
303
304 @Parameter
305 private String mergeManifestMode;
306
307
308
309
310 @Component
311 private AssemblyArchiver assemblyArchiver;
312
313
314
315
316 @Component
317 private AssemblyReader assemblyReader;
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336 @Parameter
337 private PlexusConfiguration archiverConfig;
338
339
340
341
342
343
344
345 @Parameter( property = "assembly.runOnlyAtExecutionRoot", defaultValue = "false" )
346 private boolean runOnlyAtExecutionRoot;
347
348
349
350
351
352
353
354
355
356
357 @Parameter( property = "assembly.updateOnly", defaultValue = "false" )
358 private boolean updateOnly;
359
360
361
362
363
364 @Parameter( property = "assembly.useJvmChmod", defaultValue = "false" )
365 private boolean useJvmChmod;
366
367
368
369
370
371
372
373
374
375
376
377
378
379 @Parameter( property = "assembly.ignorePermissions", defaultValue = "false" )
380 private boolean ignorePermissions;
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403 @Parameter
404 private List<String> delimiters;
405
406
407
408
409
410
411
412
413 @Parameter( defaultValue = "${project.build.outputTimestamp}" )
414 private String outputTimestamp;
415
416
417
418
419 @Parameter
420 private Integer overrideUid;
421
422
423
424
425 @Parameter
426 private String overrideUserName;
427
428
429
430
431
432 @Parameter
433 private Integer overrideGid;
434
435
436
437
438 @Parameter
439 private String overrideGroupName;
440
441
442 public static FixedStringSearchInterpolator mainProjectInterpolator( MavenProject mainProject )
443 {
444 if ( mainProject != null )
445 {
446
447 return FixedStringSearchInterpolator.create(
448 new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
449 InterpolationConstants.PROJECT_PREFIXES, mainProject, true ),
450
451
452 new org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource(
453 InterpolationConstants.PROJECT_PROPERTIES_PREFIXES, mainProject.getProperties(), true ) );
454 }
455 else
456 {
457 return FixedStringSearchInterpolator.empty();
458 }
459 }
460
461
462
463
464 @Override
465 public void execute() throws MojoExecutionException, MojoFailureException
466 {
467
468 if ( skipAssembly )
469 {
470 getLog().info( "Assemblies have been skipped per configuration of the skipAssembly parameter." );
471 return;
472 }
473
474
475 if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
476 {
477 getLog().info( "Skipping the assembly in this project because it's not the Execution Root" );
478 return;
479 }
480
481 List<Assembly> assemblies;
482 try
483 {
484 assemblies = assemblyReader.readAssemblies( this );
485 }
486 catch ( final AssemblyReadException e )
487 {
488 throw new MojoExecutionException( "Error reading assemblies: " + e.getMessage(), e );
489 }
490 catch ( final InvalidAssemblerConfigurationException e )
491 {
492 throw new MojoFailureException( assemblyReader, e.getMessage(),
493 "Mojo configuration is invalid: " + e.getMessage() );
494 }
495
496
497
498
499 MavenArchiver mavenArchiver = new MavenArchiver();
500 Date outputDate = mavenArchiver.parseOutputTimestamp( outputTimestamp );
501
502 boolean warnedAboutMainProjectArtifact = false;
503 for ( final Assembly assembly : assemblies )
504 {
505 try
506 {
507 final String fullName = AssemblyFormatUtils.getDistributionName( assembly, this );
508
509 List<String> effectiveFormats = formats;
510 if ( effectiveFormats == null || effectiveFormats.size() == 0 )
511 {
512 effectiveFormats = assembly.getFormats();
513 }
514 if ( effectiveFormats == null || effectiveFormats.size() == 0 )
515 {
516 throw new MojoFailureException(
517 "No formats specified in the execution parameters or the assembly descriptor." );
518 }
519
520 for ( final String format : effectiveFormats )
521 {
522 final File destFile = assemblyArchiver.createArchive( assembly, fullName, format, this,
523 isRecompressZippedFiles(), getMergeManifestMode(), outputDate );
524
525 final MavenProject project = getProject();
526 final String type = project.getArtifact().getType();
527
528 if ( attach && destFile.isFile() )
529 {
530 if ( isAssemblyIdAppended() )
531 {
532 projectHelper.attachArtifact( project, format, assembly.getId(), destFile );
533 }
534 else if ( !"pom".equals( type ) && format.equals( type ) )
535 {
536 if ( !warnedAboutMainProjectArtifact )
537 {
538 final StringBuilder message = new StringBuilder();
539
540 message.append( "Configuration option 'appendAssemblyId' is set to false." );
541 message.append( "\nInstead of attaching the assembly file: " ).append( destFile );
542 message.append( ", it will become the file for main project artifact." );
543 message.append(
544 "\nNOTE: If multiple descriptors or descriptor-formats are provided "
545 + "for this project, the value of this file will be "
546 + "non-deterministic!" );
547
548 getLog().warn( message );
549 warnedAboutMainProjectArtifact = true;
550 }
551
552 final File existingFile = project.getArtifact().getFile();
553 if ( ( existingFile != null ) && existingFile.exists() )
554 {
555 getLog().warn(
556 "Replacing pre-existing project main-artifact file: "
557 + existingFile + "\nwith assembly file: " + destFile );
558 }
559
560 project.getArtifact().setFile( destFile );
561 }
562 else
563 {
564 projectHelper.attachArtifact( project, format, null, destFile );
565 }
566 }
567 else if ( attach )
568 {
569 getLog().warn(
570 "Assembly file: " + destFile + " is not a regular file (it may be a directory). "
571 + "It cannot be attached to the project build for installation or "
572 + "deployment." );
573 }
574 }
575 }
576 catch ( final ArchiveCreationException | AssemblyFormattingException e )
577 {
578 throw new MojoExecutionException( "Failed to create assembly: " + e.getMessage(), e );
579 }
580 catch ( final InvalidAssemblerConfigurationException e )
581 {
582 throw new MojoFailureException( assembly, "Assembly is incorrectly configured: " + assembly.getId(),
583 "Assembly: " + assembly.getId() + " is not configured correctly: " + e.getMessage() );
584 }
585 }
586 }
587
588 private FixedStringSearchInterpolator createRepositoryInterpolator()
589 {
590 final Properties settingsProperties = new Properties();
591 final MavenSession session = getMavenSession();
592
593 if ( getLocalRepository() != null )
594 {
595 settingsProperties.setProperty( "localRepository", getLocalRepository().getBasedir() );
596 settingsProperties.setProperty( "settings.localRepository", getLocalRepository().getBasedir() );
597 }
598 else if ( session != null && session.getSettings() != null )
599 {
600 settingsProperties.setProperty( "localRepository", session.getSettings().getLocalRepository() );
601 settingsProperties.setProperty( "settings.localRepository", getLocalRepository().getBasedir() );
602 }
603
604 return FixedStringSearchInterpolator.create( new PropertiesBasedValueSource( settingsProperties ) );
605
606 }
607
608 private FixedStringSearchInterpolator createCommandLinePropertiesInterpolator()
609 {
610 Properties commandLineProperties = System.getProperties();
611 final MavenSession session = getMavenSession();
612
613 if ( session != null )
614 {
615 commandLineProperties = new Properties();
616 commandLineProperties.putAll( session.getSystemProperties() );
617 commandLineProperties.putAll( session.getUserProperties() );
618 }
619
620 PropertiesBasedValueSource cliProps = new PropertiesBasedValueSource( commandLineProperties );
621 return FixedStringSearchInterpolator.create( cliProps );
622
623 }
624
625 private FixedStringSearchInterpolator createEnvInterpolator()
626 {
627 try
628 {
629 PrefixedPropertiesValueSource envProps =
630 new PrefixedPropertiesValueSource( Collections.singletonList( "env." ),
631 CommandLineUtils.getSystemEnvVars( false ), true );
632 return FixedStringSearchInterpolator.create( envProps );
633 }
634 catch ( IOException e )
635 {
636 throw new UncheckedIOException( e );
637 }
638 }
639
640
641
642
643
644
645 boolean isThisTheExecutionRoot()
646 {
647 final Log log = getLog();
648 log.debug( "Root Folder:" + mavenSession.getExecutionRootDirectory() );
649 log.debug( "Current Folder:" + basedir );
650 final boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase( basedir.toString() );
651 if ( result )
652 {
653 log.debug( "This is the execution root." );
654 }
655 else
656 {
657 log.debug( "This is NOT the execution root." );
658 }
659
660 return result;
661 }
662
663 @Override
664 public File getBasedir()
665 {
666 return basedir;
667 }
668
669 public void setBasedir( final File basedir )
670 {
671 this.basedir = basedir;
672 }
673
674 @Override
675 public String[] getDescriptorReferences()
676 {
677 return descriptorRefs;
678 }
679
680 @Override
681 public File getDescriptorSourceDirectory()
682 {
683 return descriptorSourceDirectory;
684 }
685
686 @Override
687 public String[] getDescriptors()
688 {
689 return descriptors;
690 }
691
692 public void setDescriptors( final String[] descriptors )
693 {
694 this.descriptors = descriptors;
695 }
696
697 @Override
698 public abstract MavenProject getProject();
699
700 @Override
701 public File getSiteDirectory()
702 {
703 return siteDirectory;
704 }
705
706 public void setSiteDirectory( final File siteDirectory )
707 {
708 this.siteDirectory = siteDirectory;
709 }
710
711 @Override
712 public String getFinalName()
713 {
714 return finalName;
715 }
716
717 public void setFinalName( final String finalName )
718 {
719 this.finalName = finalName;
720 }
721
722 @Override
723 public boolean isAssemblyIdAppended()
724 {
725 return appendAssemblyId;
726 }
727
728 @Override
729 public String getTarLongFileMode()
730 {
731 return tarLongFileMode;
732 }
733
734 public void setTarLongFileMode( final String tarLongFileMode )
735 {
736 this.tarLongFileMode = tarLongFileMode;
737 }
738
739 @Override
740 public File getOutputDirectory()
741 {
742 return outputDirectory;
743 }
744
745 public void setOutputDirectory( final File outputDirectory )
746 {
747 this.outputDirectory = outputDirectory;
748 }
749
750 @Override
751 public MavenArchiveConfiguration getJarArchiveConfiguration()
752 {
753 return archive;
754 }
755
756 @Override
757 public File getWorkingDirectory()
758 {
759 return workDirectory;
760 }
761
762 @Override
763 public ArtifactRepository getLocalRepository()
764 {
765 return localRepository;
766 }
767
768 public void setLocalRepository( final ArtifactRepository localRepository )
769 {
770 this.localRepository = localRepository;
771 }
772
773 @Override
774 public File getTemporaryRootDirectory()
775 {
776 return tempRoot;
777 }
778
779 @Override
780 public File getArchiveBaseDirectory()
781 {
782 return archiveBaseDirectory;
783 }
784
785 @Override
786 public List<String> getFilters()
787 {
788 if ( filters == null )
789 {
790 filters = getProject().getBuild().getFilters();
791 if ( filters == null )
792 {
793 filters = Collections.emptyList();
794 }
795 }
796 return filters;
797 }
798
799 public void setFilters( final List<String> filters )
800 {
801 this.filters = filters;
802 }
803
804 public Properties getAdditionalProperties()
805 {
806 return additionalProperties;
807 }
808
809 @Override
810 public boolean isIncludeProjectBuildFilters()
811 {
812 return includeProjectBuildFilters;
813 }
814
815 @Override
816 public List<MavenProject> getReactorProjects()
817 {
818 return reactorProjects;
819 }
820
821 public void setReactorProjects( final List<MavenProject> reactorProjects )
822 {
823 this.reactorProjects = reactorProjects;
824 }
825
826 public void setAppendAssemblyId( final boolean appendAssemblyId )
827 {
828 this.appendAssemblyId = appendAssemblyId;
829 }
830
831 public void setArchive( final MavenArchiveConfiguration archive )
832 {
833 this.archive = archive;
834 }
835
836 public void setDescriptorRefs( final String[] descriptorRefs )
837 {
838 this.descriptorRefs = descriptorRefs;
839 }
840
841 public void setTempRoot( final File tempRoot )
842 {
843 this.tempRoot = tempRoot;
844 }
845
846 public void setWorkDirectory( final File workDirectory )
847 {
848 this.workDirectory = workDirectory;
849 }
850
851 @Override
852 public List<ArtifactRepository> getRemoteRepositories()
853 {
854 return remoteRepositories;
855 }
856
857 @Override
858 public boolean isDryRun()
859 {
860 return dryRun;
861 }
862
863 @Override
864 public boolean isIgnoreDirFormatExtensions()
865 {
866 return ignoreDirFormatExtensions;
867 }
868
869 @Override
870 public boolean isIgnoreMissingDescriptor()
871 {
872 return ignoreMissingDescriptor;
873 }
874
875 @Override
876 public MavenSession getMavenSession()
877 {
878 return mavenSession;
879 }
880
881 @Override
882 public String getArchiverConfig()
883 {
884 return archiverConfig == null ? null : archiverConfig.toString();
885 }
886
887 @Override
888 public MavenReaderFilter getMavenReaderFilter()
889 {
890 return mavenReaderFilter;
891 }
892
893 @Override
894 public boolean isUpdateOnly()
895 {
896 return updateOnly;
897 }
898
899 @Override
900 @Deprecated
901 public boolean isUseJvmChmod()
902 {
903 return useJvmChmod;
904 }
905
906 @Override
907 public boolean isIgnorePermissions()
908 {
909 return ignorePermissions;
910 }
911
912 @Override
913 public String getEncoding()
914 {
915 return encoding;
916 }
917
918 boolean isRecompressZippedFiles()
919 {
920 return recompressZippedFiles;
921 }
922
923 public String getMergeManifestMode()
924 {
925 return mergeManifestMode;
926 }
927
928 @Override
929 public String getEscapeString()
930 {
931 return escapeString;
932 }
933
934 @Override
935 public List<String> getDelimiters()
936 {
937 return delimiters;
938 }
939
940 public void setDelimiters( List<String> delimiters )
941 {
942 this.delimiters = delimiters;
943 }
944
945 @Override
946 public synchronized FixedStringSearchInterpolator getCommandLinePropsInterpolator()
947 {
948 if ( commandLinePropertiesInterpolator == null )
949 {
950 this.commandLinePropertiesInterpolator = createCommandLinePropertiesInterpolator();
951 }
952 return commandLinePropertiesInterpolator;
953 }
954
955 @Override
956 public synchronized FixedStringSearchInterpolator getEnvInterpolator()
957 {
958 if ( envInterpolator == null )
959 {
960 this.envInterpolator = createEnvInterpolator();
961 }
962 return envInterpolator;
963 }
964
965 @Override
966 public synchronized FixedStringSearchInterpolator getRepositoryInterpolator()
967 {
968 if ( rootInterpolator == null )
969 {
970 this.rootInterpolator = createRepositoryInterpolator();
971 }
972 return rootInterpolator;
973 }
974
975 @Override
976 public synchronized FixedStringSearchInterpolator getMainProjectInterpolator()
977 {
978 if ( mainProjectInterpolator == null )
979 {
980 this.mainProjectInterpolator = mainProjectInterpolator( getProject() );
981 }
982 return mainProjectInterpolator;
983 }
984
985 @Override
986 public Integer getOverrideUid()
987 {
988 return this.overrideUid;
989 }
990
991 @Override
992 public String getOverrideUserName()
993 {
994 return this.overrideUserName;
995 }
996
997 @Override
998 public Integer getOverrideGid()
999 {
1000 return this.overrideGid;
1001 }
1002
1003 @Override
1004 public String getOverrideGroupName()
1005 {
1006 return this.overrideGroupName;
1007 }
1008 }