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