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