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