1 package org.apache.maven.plugins.assembly.archive.task;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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 }