View Javadoc
1   package org.apache.maven.plugin.assembly.archive.task;
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.artifact.Artifact;
23  import org.apache.maven.plugin.assembly.AssemblerConfigurationSource;
24  import org.apache.maven.plugin.assembly.archive.ArchiveCreationException;
25  import org.apache.maven.plugin.assembly.format.AssemblyFormattingException;
26  import org.apache.maven.plugin.assembly.utils.AssemblyFormatUtils;
27  import org.apache.maven.plugin.assembly.utils.TypeConversionUtils;
28  import org.apache.maven.project.MavenProject;
29  import org.codehaus.plexus.archiver.Archiver;
30  import org.codehaus.plexus.archiver.ArchiverException;
31  import org.codehaus.plexus.archiver.util.DefaultArchivedFileSet;
32  import org.codehaus.plexus.archiver.util.DefaultFileSet;
33  import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
34  import org.codehaus.plexus.logging.Logger;
35  import org.codehaus.plexus.util.FileUtils;
36  import org.codehaus.plexus.util.StringUtils;
37  
38  import java.io.File;
39  import java.io.IOException;
40  import java.nio.charset.Charset;
41  import java.util.List;
42  
43  import static org.apache.maven.plugin.assembly.utils.AssemblyFormatUtils.artifactProjectInterpolator;
44  import static org.apache.maven.plugin.assembly.utils.AssemblyFormatUtils.moduleProjectInterpolator;
45  
46  /**
47   * @version $Id: AddArtifactTask.java 1674674 2015-04-19 19:14:00Z krosenvold $
48   */
49  public class AddArtifactTask
50  {
51  
52      public static final String[] DEFAULT_INCLUDES_ARRAY = { "**/*" };
53  
54      private int directoryMode = -1;
55  
56      private int fileMode = -1;
57  
58      private boolean unpack = false;
59  
60      private List<String> includes;
61  
62      private List<String> excludes;
63  
64      private final Artifact artifact;
65  
66      private MavenProject project;
67  
68      private MavenProject moduleProject;
69  
70      private Artifact moduleArtifact;
71  
72      private String outputDirectory;
73  
74      private String outputFileNameMapping;
75  
76      private final Logger logger;
77  
78      private final InputStreamTransformer transformer;
79  
80      private final Charset encoding;
81  
82      public AddArtifactTask( final Artifact artifact, final Logger logger, InputStreamTransformer transformer,
83                              Charset encoding )
84      {
85          this.artifact = artifact;
86          this.logger = logger;
87          this.transformer = transformer;
88          this.encoding = encoding;
89      }
90  
91      public AddArtifactTask( final Artifact artifact, final Logger logger, Charset encoding )
92      {
93          this( artifact, logger, null, encoding );
94      }
95  
96      public void execute( final Archiver archiver, final AssemblerConfigurationSource configSource )
97          throws ArchiveCreationException, AssemblyFormattingException
98      {
99          if ( artifactIsArchiverDestination( archiver ) )
100         {
101             artifact.setFile( moveArtifactSomewhereElse( configSource ) );
102         }
103 
104         String destDirectory =
105             AssemblyFormatUtils.getOutputDirectory( outputDirectory, configSource.getFinalName(), configSource,
106                                                     moduleProjectInterpolator( moduleProject ),
107                                                     artifactProjectInterpolator( project ) );
108 
109         boolean fileModeSet = false;
110         boolean dirModeSet = false;
111 
112         final int oldDirMode = archiver.getOverrideDirectoryMode();
113         final int oldFileMode = archiver.getOverrideFileMode();
114 
115         if ( fileMode != -1 )
116         {
117             archiver.setFileMode( fileMode );
118             fileModeSet = true;
119         }
120 
121         if ( directoryMode != -1 )
122         {
123             archiver.setDirectoryMode( directoryMode );
124             dirModeSet = true;
125         }
126         try
127         {
128 
129             if ( unpack )
130             {
131                 unpacked( archiver, destDirectory );
132             }
133             else
134             {
135                 asFile( archiver, configSource, destDirectory );
136             }
137         }
138         finally
139         {
140             if ( dirModeSet )
141             {
142                 archiver.setDirectoryMode( oldDirMode );
143             }
144 
145             if ( fileModeSet )
146             {
147                 archiver.setFileMode( oldFileMode );
148             }
149         }
150 
151     }
152 
153     private void asFile( Archiver archiver, AssemblerConfigurationSource configSource, String destDirectory )
154         throws AssemblyFormattingException, ArchiveCreationException
155     {
156         final String tempMapping =
157             AssemblyFormatUtils.evaluateFileNameMapping( outputFileNameMapping, artifact, configSource.getProject(),
158                                                          moduleArtifact, configSource,
159                                                          moduleProjectInterpolator( moduleProject ),
160                                                          artifactProjectInterpolator( project ) );
161 
162         final String outputLocation = destDirectory + tempMapping;
163 
164         try
165         {
166             final File artifactFile = artifact.getFile();
167 
168             logger.debug(
169                 "Adding artifact: " + artifact.getId() + " with file: " + artifactFile + " to assembly location: "
170                     + outputLocation + "." );
171 
172             if ( fileMode != -1 )
173             {
174                 archiver.addFile( artifactFile, outputLocation, fileMode );
175             }
176             else
177             {
178                 archiver.addFile( artifactFile, outputLocation );
179             }
180         }
181         catch ( final ArchiverException e )
182         {
183             throw new ArchiveCreationException(
184                 "Error adding file '" + artifact.getId() + "' to archive: " + e.getMessage(), e );
185         }
186     }
187 
188     private void unpacked( Archiver archiver, String destDirectory )
189         throws ArchiveCreationException
190     {
191         String outputLocation = destDirectory;
192 
193         if ( ( outputLocation.length() > 0 ) && !outputLocation.endsWith( "/" ) )
194         {
195             outputLocation += "/";
196         }
197 
198         String[] includesArray = TypeConversionUtils.toStringArray( includes );
199         if ( includesArray == null )
200         {
201             includesArray = DEFAULT_INCLUDES_ARRAY;
202         }
203         final String[] excludesArray = TypeConversionUtils.toStringArray( excludes );
204 
205         try
206         {
207 
208             final File artifactFile = artifact.getFile();
209             if ( artifactFile == null )
210             {
211                 logger.warn(
212                     "Skipping artifact: " + artifact.getId() + "; it does not have an associated file or directory." );
213             }
214             else if ( artifactFile.isDirectory() )
215             {
216                 logger.debug( "Adding artifact directory contents for: " + artifact + " to: " + outputLocation );
217 
218                 DefaultFileSet fs = DefaultFileSet.fileSet( artifactFile );
219                 fs.setIncludes( includesArray );
220                 fs.setExcludes( excludesArray );
221                 fs.setPrefix( outputLocation );
222                 fs.setStreamTransformer( transformer );
223                 archiver.addFileSet( fs );
224             }
225             else
226             {
227                 logger.debug( "Unpacking artifact contents for: " + artifact + " to: " + outputLocation );
228                 logger.debug( "includes:\n" + StringUtils.join( includesArray, "\n" ) + "\n" );
229                 logger.debug(
230                     "excludes:\n" + ( excludesArray == null ? "none" : StringUtils.join( excludesArray, "\n" ) )
231                         + "\n" );
232                 DefaultArchivedFileSet afs = DefaultArchivedFileSet.archivedFileSet( artifactFile );
233                 afs.setIncludes( includesArray );
234                 afs.setExcludes( excludesArray );
235                 afs.setPrefix( outputLocation );
236                 afs.setStreamTransformer( transformer );
237                 archiver.addArchivedFileSet( afs, encoding );
238             }
239         }
240         catch ( final ArchiverException e )
241         {
242             throw new ArchiveCreationException(
243                 "Error adding file-set for '" + artifact.getId() + "' to archive: " + e.getMessage(), e );
244         }
245     }
246 
247     private File moveArtifactSomewhereElse( AssemblerConfigurationSource configSource )
248         throws ArchiveCreationException
249     {
250         final File tempRoot = configSource.getTemporaryRootDirectory();
251         final File tempArtifactFile = new File( tempRoot, artifact.getFile().getName() );
252 
253         logger.warn( "Artifact: " + artifact.getId() + " references the same file as the assembly destination file. "
254                          + "Moving it to a temporary location for inclusion." );
255         try
256         {
257             FileUtils.copyFile( artifact.getFile(), tempArtifactFile );
258         }
259         catch ( final IOException e )
260         {
261             throw new ArchiveCreationException(
262                 "Error moving artifact file: '" + artifact.getFile() + "' to temporary location: " + tempArtifactFile
263                     + ". Reason: " + e.getMessage(), e );
264         }
265         return tempArtifactFile;
266     }
267 
268     private boolean artifactIsArchiverDestination( Archiver archiver )
269     {
270         return ( ( artifact.getFile() != null ) && ( archiver.getDestFile() != null ) ) && artifact.getFile().equals(
271             archiver.getDestFile() );
272     }
273 
274     public void setDirectoryMode( final int directoryMode )
275     {
276         this.directoryMode = directoryMode;
277     }
278 
279     public void setFileMode( final int fileMode )
280     {
281         this.fileMode = fileMode;
282     }
283 
284     public void setExcludes( final List<String> excludes )
285     {
286         this.excludes = excludes;
287     }
288 
289     public void setIncludes( final List<String> includes )
290     {
291         this.includes = includes;
292     }
293 
294     public void setUnpack( final boolean unpack )
295     {
296         this.unpack = unpack;
297     }
298 
299     public void setProject( final MavenProject project )
300     {
301         this.project = project;
302     }
303 
304     public void setOutputDirectory( final String outputDirectory )
305     {
306         this.outputDirectory = outputDirectory;
307     }
308 
309     public void setFileNameMapping( final String outputFileNameMapping )
310     {
311         this.outputFileNameMapping = outputFileNameMapping;
312     }
313 
314     public void setOutputDirectory( final String outputDirectory, final String defaultOutputDirectory )
315     {
316         setOutputDirectory( outputDirectory == null ? defaultOutputDirectory : outputDirectory );
317     }
318 
319     public void setFileNameMapping( final String outputFileNameMapping, final String defaultOutputFileNameMapping )
320     {
321         setFileNameMapping( outputFileNameMapping == null ? defaultOutputFileNameMapping : outputFileNameMapping );
322     }
323 
324     public void setModuleProject( final MavenProject moduleProject )
325     {
326         this.moduleProject = moduleProject;
327     }
328 
329     public void setModuleArtifact( final Artifact moduleArtifact )
330     {
331         this.moduleArtifact = moduleArtifact;
332     }
333 
334 }