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 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 }