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.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
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 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, final Logger logger, InputStreamTransformer transformer,
82 Charset encoding )
83 {
84 this.artifact = artifact;
85 this.logger = logger;
86 this.transformer = transformer;
87 this.encoding = encoding;
88 }
89
90 public AddArtifactTask( final Artifact artifact, final Logger logger, Charset encoding )
91 {
92 this( artifact, logger, null, encoding );
93 }
94
95 public void execute( final Archiver archiver, final AssemblerConfigurationSource configSource )
96 throws ArchiveCreationException, AssemblyFormattingException
97 {
98 if ( artifactIsArchiverDestination( archiver ) )
99 {
100 artifact.setFile( moveArtifactSomewhereElse( configSource ) );
101 }
102
103 String destDirectory =
104 AssemblyFormatUtils.getOutputDirectory( outputDirectory, configSource.getFinalName(), configSource,
105 AssemblyFormatUtils.moduleProjectInterpolator( moduleProject ),
106 AssemblyFormatUtils.artifactProjectInterpolator( project ) );
107
108 boolean fileModeSet = false;
109 boolean dirModeSet = false;
110
111 final int oldDirMode = archiver.getOverrideDirectoryMode();
112 final int oldFileMode = archiver.getOverrideFileMode();
113
114 if ( fileMode != -1 )
115 {
116 archiver.setFileMode( fileMode );
117 fileModeSet = true;
118 }
119
120 if ( directoryMode != -1 )
121 {
122 archiver.setDirectoryMode( directoryMode );
123 dirModeSet = true;
124 }
125 try
126 {
127
128 if ( unpack )
129 {
130 unpacked( archiver, destDirectory );
131 }
132 else
133 {
134 asFile( archiver, configSource, destDirectory );
135 }
136 }
137 finally
138 {
139 if ( dirModeSet )
140 {
141 archiver.setDirectoryMode( oldDirMode );
142 }
143
144 if ( fileModeSet )
145 {
146 archiver.setFileMode( oldFileMode );
147 }
148 }
149
150 }
151
152 private void asFile( Archiver archiver, AssemblerConfigurationSource configSource, String destDirectory )
153 throws AssemblyFormattingException, ArchiveCreationException
154 {
155 final String tempMapping =
156 AssemblyFormatUtils.evaluateFileNameMapping( outputFileNameMapping, artifact, configSource.getProject(),
157 moduleArtifact, configSource,
158 AssemblyFormatUtils.moduleProjectInterpolator( moduleProject ),
159 AssemblyFormatUtils.artifactProjectInterpolator( project ) );
160
161 final String outputLocation = destDirectory + tempMapping;
162
163 try
164 {
165 final File artifactFile = artifact.getFile();
166
167 logger.debug(
168 "Adding artifact: " + artifact.getId() + " with file: " + artifactFile + " to assembly location: "
169 + outputLocation + "." );
170
171 if ( fileMode != -1 )
172 {
173 archiver.addFile( artifactFile, outputLocation, fileMode );
174 }
175 else
176 {
177 archiver.addFile( artifactFile, outputLocation );
178 }
179 }
180 catch ( final ArchiverException e )
181 {
182 throw new ArchiveCreationException(
183 "Error adding file '" + artifact.getId() + "' to archive: " + e.getMessage(), e );
184 }
185 }
186
187 private void unpacked( Archiver archiver, String destDirectory )
188 throws ArchiveCreationException
189 {
190 String outputLocation = destDirectory;
191
192 if ( ( outputLocation.length() > 0 ) && !outputLocation.endsWith( "/" ) )
193 {
194 outputLocation += "/";
195 }
196
197 String[] includesArray = TypeConversionUtils.toStringArray( includes );
198 if ( includesArray == null )
199 {
200 includesArray = DEFAULT_INCLUDES_ARRAY;
201 }
202 final String[] excludesArray = TypeConversionUtils.toStringArray( excludes );
203
204 try
205 {
206
207 final File artifactFile = artifact.getFile();
208 if ( artifactFile == null )
209 {
210 logger.warn(
211 "Skipping artifact: " + artifact.getId() + "; it does not have an associated file or directory." );
212 }
213 else if ( artifactFile.isDirectory() )
214 {
215 logger.debug( "Adding artifact directory contents for: " + artifact + " to: " + outputLocation );
216
217 DefaultFileSet fs = DefaultFileSet.fileSet( artifactFile );
218 fs.setIncludes( includesArray );
219 fs.setExcludes( excludesArray );
220 fs.setPrefix( outputLocation );
221 fs.setStreamTransformer( transformer );
222 fs.setUsingDefaultExcludes( usingDefaultExcludes );
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 afs.setUsingDefaultExcludes( usingDefaultExcludes );
238 archiver.addArchivedFileSet( afs, encoding );
239 }
240 }
241 catch ( final ArchiverException e )
242 {
243 throw new ArchiveCreationException(
244 "Error adding file-set for '" + artifact.getId() + "' to archive: " + e.getMessage(), e );
245 }
246 }
247
248 private File moveArtifactSomewhereElse( AssemblerConfigurationSource configSource )
249 throws ArchiveCreationException
250 {
251 final File tempRoot = configSource.getTemporaryRootDirectory();
252 final File tempArtifactFile = new File( tempRoot, artifact.getFile().getName() );
253
254 logger.warn( "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 }