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