View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.assembly.mojos;
20  
21  import java.io.File;
22  import java.nio.file.attribute.FileTime;
23  import java.util.Collections;
24  import java.util.List;
25  import java.util.Properties;
26  
27  import org.apache.maven.archiver.MavenArchiveConfiguration;
28  import org.apache.maven.archiver.MavenArchiver;
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.execution.MavenSession;
31  import org.apache.maven.plugin.AbstractMojo;
32  import org.apache.maven.plugin.MojoExecutionException;
33  import org.apache.maven.plugin.MojoFailureException;
34  import org.apache.maven.plugin.logging.Log;
35  import org.apache.maven.plugins.annotations.Component;
36  import org.apache.maven.plugins.annotations.Parameter;
37  import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
38  import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
39  import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
40  import org.apache.maven.plugins.assembly.archive.AssemblyArchiver;
41  import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
42  import org.apache.maven.plugins.assembly.io.AssemblyReadException;
43  import org.apache.maven.plugins.assembly.io.AssemblyReader;
44  import org.apache.maven.plugins.assembly.model.Assembly;
45  import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
46  import org.apache.maven.plugins.assembly.utils.InterpolationConstants;
47  import org.apache.maven.project.MavenProject;
48  import org.apache.maven.project.MavenProjectHelper;
49  import org.apache.maven.shared.filtering.MavenReaderFilter;
50  import org.codehaus.plexus.configuration.PlexusConfiguration;
51  import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
52  import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
53  import org.codehaus.plexus.interpolation.fixed.PropertiesBasedValueSource;
54  import org.codehaus.plexus.util.cli.CommandLineUtils;
55  
56  /**
57   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
58   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
59   */
60  public abstract class AbstractAssemblyMojo extends AbstractMojo implements AssemblerConfigurationSource {
61  
62      protected FixedStringSearchInterpolator commandLinePropertiesInterpolator;
63  
64      protected FixedStringSearchInterpolator envInterpolator;
65  
66      protected FixedStringSearchInterpolator mainProjectInterpolator;
67  
68      protected FixedStringSearchInterpolator rootInterpolator;
69  
70      /**
71       * Set to false to exclude the assembly id from the assembly final name, and to create the resultant assembly
72       * artifacts without classifier. As such, an assembly artifact having the same format as the packaging of the
73       * current Maven project will replace the file for this main project artifact.
74       */
75      @Parameter(property = "assembly.appendAssemblyId", defaultValue = "true")
76      boolean appendAssemblyId;
77  
78      /**
79       * The character encoding scheme to be applied when filtering resources.
80       */
81      @Parameter(property = "encoding", defaultValue = "${project.build.sourceEncoding}")
82      private String encoding;
83  
84      /**
85       * Expressions preceded with this String won't be interpolated. If you use "\" as the escape string then \${foo}
86       * will be replaced with ${foo}.
87       *
88       * @since 2.4
89       */
90      @Parameter(property = "assembly.escapeString")
91      private String escapeString;
92  
93      /**
94       * Flag allowing one or more executions of the assembly plugin to be configured as skipped for a particular build.
95       * This makes the assembly plugin more controllable from profiles.
96       */
97      @Parameter(property = "assembly.skipAssembly", defaultValue = "false")
98      private boolean skipAssembly;
99  
100     /**
101      * If this flag is set, everything up to the call to Archiver.createArchive() will be executed.
102      */
103     @Parameter(property = "assembly.dryRun", defaultValue = "false")
104     private boolean dryRun;
105 
106     /**
107      * If this flag is set, the ".dir" suffix will be suppressed in the output directory name when using assembly/format
108      * == 'dir' and other formats that begin with 'dir'. <br/>
109      * <b>NOTE:</b> Since 2.2-beta-3, the default-value for this is true, NOT false as it used to be.
110      */
111     @Parameter(defaultValue = "true")
112     private boolean ignoreDirFormatExtensions;
113 
114     /**
115      *
116      */
117     @Parameter(defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true)
118     private List<ArtifactRepository> remoteRepositories;
119 
120     /**
121      * Contains the full list of projects in the reactor.
122      */
123     @Parameter(defaultValue = "${reactorProjects}", required = true, readonly = true)
124     private List<MavenProject> reactorProjects;
125 
126     /**
127      * The output directory of the assembled distribution file.
128      */
129     @Parameter(defaultValue = "${project.build.directory}", required = true)
130     private File outputDirectory;
131 
132     /**
133      * The filename of the assembled distribution file.<br/>
134      * <b>NOTE:</b> This parameter has only impact on name in project target directory,
135      * installed/deployed artifacts will follow convention for artifact names.
136      */
137     @Parameter(defaultValue = "${project.build.finalName}", required = true)
138     private String finalName;
139 
140     /**
141      * Directory to unpack JARs into if needed
142      */
143     @Parameter(defaultValue = "${project.build.directory}/assembly/work", required = true)
144     private File workDirectory;
145 
146     /**
147      * Specifies the formats of the assembly. Multiple formats can be supplied and the Assembly Plugin will generate an
148      * archive for each desired formats. When deploying your project, all file formats specified will also be deployed.
149      * A format is specified by supplying one of the following values in a &lt;format&gt; subelement:
150      * <ul>
151      * <li><em>dir</em> - Creates a directory</li>
152      * <li><em>zip</em> - Creates a ZIP file format</li>
153      * <li><em>tar</em> - Creates a TAR format</li>
154      * <li><em>tar.gz</em> or <em>tgz</em> - Creates a gzip'd TAR format</li>
155      * <li><em>tar.bz2</em> or <em>tbz2</em> - Creates a bzip'd TAR format</li>
156      * <li><em>tar.snappy</em> - Creates a snappy'd TAR format</li>
157      * <li><em>tar.xz</em> or <em>txz</em> - Creates a xz'd TAR format</li>
158      * <li><em>tar.zst</em> or <em>tzst</em> - Creates a zst'd TAR format</li>
159      * </ul>
160      */
161     @Parameter
162     private List<String> formats;
163 
164     /**
165      * A list of descriptor files to generate from.
166      */
167     @Parameter
168     private String[] descriptors;
169 
170     /**
171      * A list of references to assembly descriptors available on the plugin's classpath. The default classpath includes
172      * these built-in descriptors: <code>bin</code>, <code>jar-with-dependencies</code>, <code>src</code>, and
173      * <code>project</code>. You can add others by adding dependencies
174      * to the plugin.
175      */
176     @Parameter
177     private String[] descriptorRefs;
178 
179     /**
180      * Directory to scan for descriptor files in. <b>NOTE:</b> This may not work correctly with assembly components.
181      */
182     @Parameter
183     private File descriptorSourceDirectory;
184 
185     /**
186      * This is the base directory from which archive files are created. This base directory pre-pended to any
187      * <code>&lt;directory&gt;</code> specifications in the assembly descriptor. This is an optional parameter.
188      */
189     @Parameter
190     private File archiveBaseDirectory;
191 
192     /**
193      * Sets the TarArchiver behavior on file paths with more than 100 characters length. Valid values are: "warn"
194      * (default), "fail", "truncate", "gnu", "posix", "posix_warn" or "omit".
195      */
196     @Parameter(property = "assembly.tarLongFileMode", defaultValue = "warn")
197     private String tarLongFileMode;
198 
199     /**
200      * Base directory of the project.
201      */
202     @Parameter(defaultValue = "${project.basedir}", required = true, readonly = true)
203     private File basedir;
204 
205     /**
206      * Maven ProjectHelper.
207      */
208     @Component
209     private MavenProjectHelper projectHelper;
210 
211     /**
212      * Maven shared filtering utility.
213      */
214     @Component
215     private MavenReaderFilter mavenReaderFilter;
216 
217     /**
218      * The Maven Session Object
219      */
220     @Parameter(defaultValue = "${session}", readonly = true, required = true)
221     private MavenSession mavenSession;
222 
223     /**
224      * Temporary directory that contain the files to be assembled.
225      */
226     @Parameter(defaultValue = "${project.build.directory}/archive-tmp", required = true, readonly = true)
227     private File tempRoot;
228 
229     /**
230      * Directory for site generated.
231      */
232     @Parameter(defaultValue = "${project.reporting.outputDirectory}", readonly = true)
233     private File siteDirectory;
234 
235     /**
236      * Set to true in order to not fail when a descriptor is missing.
237      */
238     @Parameter(property = "assembly.ignoreMissingDescriptor", defaultValue = "false")
239     private boolean ignoreMissingDescriptor;
240 
241     /**
242      * This is a set of instructions to the archive builder, especially for building .jar files. It enables you to
243      * specify a Manifest file for the jar, in addition to other options. See
244      * <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
245      */
246     @Parameter
247     private MavenArchiveConfiguration archive;
248 
249     /**
250      * The list of extra filter properties files to be used along with System properties, project properties, and filter
251      * properties files specified in the POM build/filters section, which should be used for the filtering during the
252      * current mojo execution. <br/> Normally, these will be configured from a plugin's execution section, to provide a
253      * different set of filters for a particular execution.
254      */
255     @Parameter
256     private List<String> filters;
257 
258     /**
259      * A set of additional properties to use for filtering
260      *
261      * @since 3.3.0
262      */
263     @Parameter
264     private Properties additionalProperties;
265 
266     /**
267      * If True (default) then the ${project.build.filters} are also used in addition to any further filters defined for
268      * the Assembly.
269      *
270      * @since 2.4.2
271      */
272     @Parameter(property = "assembly.includeProjectBuildFilters", defaultValue = "true")
273     private boolean includeProjectBuildFilters;
274 
275     /**
276      * Controls whether the assembly plugin tries to attach the resulting assembly to the project.
277      *
278      * @since 2.2-beta-1
279      */
280     @Parameter(property = "assembly.attach", defaultValue = "true")
281     private boolean attach;
282 
283     /**
284      * Indicates if zip archives (jar,zip etc) being added to the assembly should be compressed again. Compressing again
285      * can result in smaller archive size, but gives noticeably longer execution time.
286      *
287      * @since 2.4
288      */
289     @Parameter(defaultValue = "true")
290     private boolean recompressZippedFiles;
291 
292     /**
293      * sets the merge manifest mode in the JarArchiver
294      *
295      * @since 3
296      */
297     @Parameter
298     private String mergeManifestMode;
299 
300     /**
301      *
302      */
303     @Component
304     private AssemblyArchiver assemblyArchiver;
305 
306     /**
307      *
308      */
309     @Component
310     private AssemblyReader assemblyReader;
311 
312     /**
313      * Allows additional configuration options that are specific to a particular type of archive format. This is
314      * intended to capture an XML configuration that will be used to reflectively setup the options on the archiver
315      * instance. <br/> To see the possible options for archiver configuration visit the
316      * <a href="https://codehaus-plexus.github.io/plexus-archiver/apidocs/org/codehaus/plexus/archiver/Archiver.html">
317      * Plexus Archiver Documentation</a> <br/> For instance, to direct an assembly with the "ear" format to use a
318      * particular deployment descriptor, you should specify the following for the archiverConfig value in your plugin
319      * configuration: <br/>
320      * <p/>
321      * <p/>
322      * <pre>
323      * &lt;appxml&gt;${project.basedir}/somepath/app.xml&lt;/appxml&gt;
324      * </pre>
325      * <p/>
326      *
327      * @since 2.2-beta-3
328      */
329     @Parameter
330     private PlexusConfiguration archiverConfig;
331 
332     /**
333      * This will cause the assembly to run only at the top of a given module tree. That is, run in the project contained
334      * in the same folder where the mvn execution was launched.
335      *
336      * @since 2.2-beta-4
337      */
338     @Parameter(property = "assembly.runOnlyAtExecutionRoot", defaultValue = "false")
339     private boolean runOnlyAtExecutionRoot;
340 
341     /**
342      * This will cause the assembly to only update an existing archive, if it exists.
343      * <p>
344      * <strong>Note:</strong> The property that can be used on the command line was misspelled as "assembly.updatOnly"
345      * in versions prior to version 2.4.
346      * </p>
347      *
348      * @since 2.2
349      */
350     @Parameter(property = "assembly.updateOnly", defaultValue = "false")
351     private boolean updateOnly;
352 
353     /**
354      * @since 2.2
355      * @deprecated Not used anymore and will be removed in future version
356      */
357     @Parameter(property = "assembly.useJvmChmod", defaultValue = "false")
358     private boolean useJvmChmod;
359 
360     /**
361      * <p>
362      * Set to <code>true</code> in order to avoid all chmod calls.
363      * </p>
364      * <p/>
365      * <p>
366      * <b>NOTE:</b> This will cause the assembly plugin to <b>DISREGARD</b> all fileMode/directoryMode settings in the
367      * assembly descriptor, and all file permissions in unpacked dependencies!
368      * </p>
369      *
370      * @since 2.2
371      */
372     @Parameter(property = "assembly.ignorePermissions", defaultValue = "false")
373     private boolean ignorePermissions;
374 
375     /**
376      * <p>
377      * Set of delimiters for expressions to filter within the resources. These delimiters are specified in the form
378      * 'beginToken*endToken'. If no '*' is given, the delimiter is assumed to be the same for start and end.
379      * </p>
380      * <p>
381      * So, the default filtering delimiters might be specified as:
382      * </p>
383      * <p/>
384      * <pre>
385      * &lt;delimiters&gt;
386      *   &lt;delimiter&gt;${*}&lt;/delimiter&gt;
387      *   &lt;delimiter&gt;@&lt;/delimiter&gt;
388      * &lt;/delimiters&gt;
389      * </pre>
390      * <p>
391      * Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can).
392      * </p>
393      *
394      * @since 2.4
395      */
396     @Parameter
397     private List<String> delimiters;
398 
399     /**
400      * Timestamp for reproducible output archive entries, either formatted as ISO 8601
401      * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
402      * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
403      *
404      * @since 3.2.0
405      */
406     @Parameter(defaultValue = "${project.build.outputTimestamp}")
407     private String outputTimestamp;
408 
409     /**
410      * Override of user ID in archive type which can store it.
411      */
412     @Parameter
413     private Integer overrideUid;
414 
415     /**
416      * Override of user name in archive type which can store it.
417      */
418     @Parameter
419     private String overrideUserName;
420 
421     /**
422      * Override of group ID in archive type which can store it.
423      */
424     @Parameter
425     private Integer overrideGid;
426 
427     /**
428      * Override of group name in archive type which can store it.
429      */
430     @Parameter
431     private String overrideGroupName;
432 
433     public static FixedStringSearchInterpolator mainProjectInterpolator(MavenProject mainProject) {
434         if (mainProject != null) {
435             // 5
436             return FixedStringSearchInterpolator.create(
437                     new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
438                             InterpolationConstants.PROJECT_PREFIXES, mainProject, true),
439 
440                     // 6
441                     new org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource(
442                             InterpolationConstants.PROJECT_PROPERTIES_PREFIXES, mainProject.getProperties(), true));
443         } else {
444             return FixedStringSearchInterpolator.empty();
445         }
446     }
447 
448     /**
449      * Create the binary distribution.
450      */
451     @Override
452     public void execute() throws MojoExecutionException, MojoFailureException {
453 
454         if (skipAssembly) {
455             getLog().info("Assemblies have been skipped per configuration of the skipAssembly parameter.");
456             return;
457         }
458 
459         // run only at the execution root.
460         if (runOnlyAtExecutionRoot && !isThisTheExecutionRoot()) {
461             getLog().info("Skipping the assembly in this project because it's not the Execution Root");
462             return;
463         }
464 
465         List<Assembly> assemblies;
466         try {
467             assemblies = assemblyReader.readAssemblies(this);
468         } catch (final AssemblyReadException e) {
469             throw new MojoExecutionException("Error reading assemblies: " + e.getMessage(), e);
470         } catch (final InvalidAssemblerConfigurationException e) {
471             throw new MojoFailureException(
472                     assemblyReader, e.getMessage(), "Mojo configuration is invalid: " + e.getMessage());
473         }
474 
475         // TODO: include dependencies marked for distribution under certain formats
476         // TODO: how, might we plug this into an installer, such as NSIS?
477 
478         FileTime outputDate = MavenArchiver.parseBuildOutputTimestamp(outputTimestamp)
479                 .map(FileTime::from)
480                 .orElse(null);
481 
482         boolean warnedAboutMainProjectArtifact = false;
483         for (final Assembly assembly : assemblies) {
484             try {
485                 final String fullName = AssemblyFormatUtils.getDistributionName(assembly, this);
486 
487                 List<String> effectiveFormats = formats;
488                 if (effectiveFormats == null || effectiveFormats.isEmpty()) {
489                     effectiveFormats = assembly.getFormats();
490                 }
491                 if (effectiveFormats == null || effectiveFormats.isEmpty()) {
492                     throw new MojoFailureException(
493                             "No formats specified in the execution parameters or the assembly descriptor.");
494                 }
495 
496                 for (final String format : effectiveFormats) {
497                     final File destFile = assemblyArchiver.createArchive(
498                             assembly,
499                             fullName,
500                             format,
501                             this,
502                             isRecompressZippedFiles(),
503                             getMergeManifestMode(),
504                             outputDate);
505 
506                     final MavenProject project = getProject();
507                     final String type = project.getArtifact().getType();
508 
509                     if (attach && destFile.isFile()) {
510                         if (isAssemblyIdAppended()) {
511                             projectHelper.attachArtifact(project, format, assembly.getId(), destFile);
512                         } else if (!"pom".equals(type) && format.equals(type)) {
513                             if (!warnedAboutMainProjectArtifact) {
514                                 final StringBuilder message = new StringBuilder();
515 
516                                 message.append("Configuration option 'appendAssemblyId' is set to false.");
517                                 message.append("\nInstead of attaching the assembly file: ")
518                                         .append(destFile);
519                                 message.append(", it will become the file for main project artifact.");
520                                 message.append("\nNOTE: If multiple descriptors or descriptor-formats are provided "
521                                         + "for this project, the value of this file will be "
522                                         + "non-deterministic!");
523 
524                                 getLog().warn(message);
525                                 warnedAboutMainProjectArtifact = true;
526                             }
527 
528                             final File existingFile = project.getArtifact().getFile();
529                             if ((existingFile != null) && existingFile.exists()) {
530                                 getLog().warn("Replacing pre-existing project main-artifact file: " + existingFile
531                                         + "\nwith assembly file: " + destFile);
532                             }
533 
534                             project.getArtifact().setFile(destFile);
535                         } else {
536                             projectHelper.attachArtifact(project, format, null, destFile);
537                         }
538                     } else if (attach) {
539                         getLog().warn("Assembly file: " + destFile + " is not a regular file (it may be a directory). "
540                                 + "It cannot be attached to the project build for installation or "
541                                 + "deployment.");
542                     }
543                 }
544             } catch (final ArchiveCreationException | AssemblyFormattingException e) {
545                 throw new MojoExecutionException("Failed to create assembly: " + e.getMessage(), e);
546             } catch (final InvalidAssemblerConfigurationException e) {
547                 throw new MojoFailureException(
548                         assembly,
549                         "Assembly is incorrectly configured: " + assembly.getId(),
550                         "Assembly: " + assembly.getId() + " is not configured correctly: " + e.getMessage());
551             }
552         }
553     }
554 
555     private FixedStringSearchInterpolator createRepositoryInterpolator() {
556         final Properties settingsProperties = new Properties();
557         final MavenSession session = getMavenSession();
558         final File basedir = session.getRepositorySession()
559                 .getLocalRepositoryManager()
560                 .getRepository()
561                 .getBasedir();
562 
563         settingsProperties.setProperty("localRepository", basedir.toString());
564         settingsProperties.setProperty("settings.localRepository", basedir.toString());
565 
566         return FixedStringSearchInterpolator.create(new PropertiesBasedValueSource(settingsProperties));
567     }
568 
569     private FixedStringSearchInterpolator createCommandLinePropertiesInterpolator() {
570         Properties commandLineProperties = System.getProperties();
571         final MavenSession session = getMavenSession();
572 
573         if (session != null) {
574             commandLineProperties = new Properties();
575             commandLineProperties.putAll(session.getSystemProperties());
576             commandLineProperties.putAll(session.getUserProperties());
577         }
578 
579         PropertiesBasedValueSource cliProps = new PropertiesBasedValueSource(commandLineProperties);
580         return FixedStringSearchInterpolator.create(cliProps);
581     }
582 
583     private FixedStringSearchInterpolator createEnvInterpolator() {
584         PrefixedPropertiesValueSource envProps = new PrefixedPropertiesValueSource(
585                 Collections.singletonList("env."), CommandLineUtils.getSystemEnvVars(false), true);
586         return FixedStringSearchInterpolator.create(envProps);
587     }
588 
589     /**
590      * Returns true if the current project is located at the Execution Root Directory (where mvn was launched)
591      *
592      * @return if this is the execution root
593      */
594     boolean isThisTheExecutionRoot() {
595         final Log log = getLog();
596         log.debug("Root Folder:" + mavenSession.getExecutionRootDirectory());
597         log.debug("Current Folder:" + basedir);
598         final boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());
599         if (result) {
600             log.debug("This is the execution root.");
601         } else {
602             log.debug("This is NOT the execution root.");
603         }
604 
605         return result;
606     }
607 
608     @Override
609     public File getBasedir() {
610         return basedir;
611     }
612 
613     public void setBasedir(final File basedir) {
614         this.basedir = basedir;
615     }
616 
617     @Override
618     public String[] getDescriptorReferences() {
619         return descriptorRefs;
620     }
621 
622     @Override
623     public File getDescriptorSourceDirectory() {
624         return descriptorSourceDirectory;
625     }
626 
627     @Override
628     public String[] getDescriptors() {
629         return descriptors;
630     }
631 
632     public void setDescriptors(final String[] descriptors) {
633         this.descriptors = descriptors;
634     }
635 
636     @Override
637     public abstract MavenProject getProject();
638 
639     @Override
640     public File getSiteDirectory() {
641         return siteDirectory;
642     }
643 
644     public void setSiteDirectory(final File siteDirectory) {
645         this.siteDirectory = siteDirectory;
646     }
647 
648     @Override
649     public String getFinalName() {
650         return finalName;
651     }
652 
653     public void setFinalName(final String finalName) {
654         this.finalName = finalName;
655     }
656 
657     @Override
658     public boolean isAssemblyIdAppended() {
659         return appendAssemblyId;
660     }
661 
662     @Override
663     public String getTarLongFileMode() {
664         return tarLongFileMode;
665     }
666 
667     public void setTarLongFileMode(final String tarLongFileMode) {
668         this.tarLongFileMode = tarLongFileMode;
669     }
670 
671     @Override
672     public File getOutputDirectory() {
673         return outputDirectory;
674     }
675 
676     public void setOutputDirectory(final File outputDirectory) {
677         this.outputDirectory = outputDirectory;
678     }
679 
680     @Override
681     public MavenArchiveConfiguration getJarArchiveConfiguration() {
682         return archive;
683     }
684 
685     @Override
686     public File getWorkingDirectory() {
687         return workDirectory;
688     }
689 
690     @Override
691     public File getTemporaryRootDirectory() {
692         return tempRoot;
693     }
694 
695     @Override
696     public File getArchiveBaseDirectory() {
697         return archiveBaseDirectory;
698     }
699 
700     @Override
701     public List<String> getFilters() {
702         if (filters == null) {
703             filters = getProject().getBuild().getFilters();
704             if (filters == null) {
705                 filters = Collections.emptyList();
706             }
707         }
708         return filters;
709     }
710 
711     public void setFilters(final List<String> filters) {
712         this.filters = filters;
713     }
714 
715     public Properties getAdditionalProperties() {
716         return additionalProperties;
717     }
718 
719     @Override
720     public boolean isIncludeProjectBuildFilters() {
721         return includeProjectBuildFilters;
722     }
723 
724     @Override
725     public List<MavenProject> getReactorProjects() {
726         return reactorProjects;
727     }
728 
729     public void setReactorProjects(final List<MavenProject> reactorProjects) {
730         this.reactorProjects = reactorProjects;
731     }
732 
733     public void setAppendAssemblyId(final boolean appendAssemblyId) {
734         this.appendAssemblyId = appendAssemblyId;
735     }
736 
737     public void setArchive(final MavenArchiveConfiguration archive) {
738         this.archive = archive;
739     }
740 
741     public void setDescriptorRefs(final String[] descriptorRefs) {
742         this.descriptorRefs = descriptorRefs;
743     }
744 
745     public void setTempRoot(final File tempRoot) {
746         this.tempRoot = tempRoot;
747     }
748 
749     public void setWorkDirectory(final File workDirectory) {
750         this.workDirectory = workDirectory;
751     }
752 
753     @Override
754     public List<ArtifactRepository> getRemoteRepositories() {
755         return remoteRepositories;
756     }
757 
758     @Override
759     public boolean isDryRun() {
760         return dryRun;
761     }
762 
763     @Override
764     public boolean isIgnoreDirFormatExtensions() {
765         return ignoreDirFormatExtensions;
766     }
767 
768     @Override
769     public boolean isIgnoreMissingDescriptor() {
770         return ignoreMissingDescriptor;
771     }
772 
773     @Override
774     public MavenSession getMavenSession() {
775         return mavenSession;
776     }
777 
778     @Override
779     public String getArchiverConfig() {
780         return archiverConfig == null ? null : archiverConfig.toString();
781     }
782 
783     @Override
784     public MavenReaderFilter getMavenReaderFilter() {
785         return mavenReaderFilter;
786     }
787 
788     @Override
789     public boolean isUpdateOnly() {
790         return updateOnly;
791     }
792 
793     @Override
794     @Deprecated
795     public boolean isUseJvmChmod() {
796         return useJvmChmod;
797     }
798 
799     @Override
800     public boolean isIgnorePermissions() {
801         return ignorePermissions;
802     }
803 
804     @Override
805     public String getEncoding() {
806         return encoding;
807     }
808 
809     boolean isRecompressZippedFiles() {
810         return recompressZippedFiles;
811     }
812 
813     public String getMergeManifestMode() {
814         return mergeManifestMode;
815     }
816 
817     @Override
818     public String getEscapeString() {
819         return escapeString;
820     }
821 
822     @Override
823     public List<String> getDelimiters() {
824         return delimiters;
825     }
826 
827     public void setDelimiters(List<String> delimiters) {
828         this.delimiters = delimiters;
829     }
830 
831     @Override
832     public synchronized FixedStringSearchInterpolator getCommandLinePropsInterpolator() {
833         if (commandLinePropertiesInterpolator == null) {
834             this.commandLinePropertiesInterpolator = createCommandLinePropertiesInterpolator();
835         }
836         return commandLinePropertiesInterpolator;
837     }
838 
839     @Override
840     public synchronized FixedStringSearchInterpolator getEnvInterpolator() {
841         if (envInterpolator == null) {
842             this.envInterpolator = createEnvInterpolator();
843         }
844         return envInterpolator;
845     }
846 
847     @Override
848     public synchronized FixedStringSearchInterpolator getRepositoryInterpolator() {
849         if (rootInterpolator == null) {
850             this.rootInterpolator = createRepositoryInterpolator();
851         }
852         return rootInterpolator;
853     }
854 
855     @Override
856     public synchronized FixedStringSearchInterpolator getMainProjectInterpolator() {
857         if (mainProjectInterpolator == null) {
858             this.mainProjectInterpolator = mainProjectInterpolator(getProject());
859         }
860         return mainProjectInterpolator;
861     }
862 
863     @Override
864     public Integer getOverrideUid() {
865         return this.overrideUid;
866     }
867 
868     @Override
869     public String getOverrideUserName() {
870         return this.overrideUserName;
871     }
872 
873     @Override
874     public Integer getOverrideGid() {
875         return this.overrideGid;
876     }
877 
878     @Override
879     public String getOverrideGroupName() {
880         return this.overrideGroupName;
881     }
882 }