1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.assembly.archive.task;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.nio.charset.Charset;
24 import java.util.List;
25
26 import org.apache.maven.artifact.Artifact;
27 import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
28 import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
29 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
30 import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
31 import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
32 import org.apache.maven.project.MavenProject;
33 import org.codehaus.plexus.archiver.Archiver;
34 import org.codehaus.plexus.archiver.ArchiverException;
35 import org.codehaus.plexus.archiver.util.DefaultArchivedFileSet;
36 import org.codehaus.plexus.archiver.util.DefaultFileSet;
37 import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
38 import org.codehaus.plexus.util.FileUtils;
39 import org.codehaus.plexus.util.StringUtils;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43
44
45
46 public class AddArtifactTask {
47 private static final Logger LOGGER = LoggerFactory.getLogger(AddArtifactTask.class);
48
49 public static final String[] DEFAULT_INCLUDES_ARRAY = {"**/*"};
50
51 private final Artifact artifact;
52
53 private final InputStreamTransformer transformer;
54
55 private final Charset encoding;
56
57 private int directoryMode = -1;
58
59 private int fileMode = -1;
60
61 private boolean unpack = false;
62
63 private List<String> includes;
64
65 private List<String> excludes;
66
67 private boolean usingDefaultExcludes = true;
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, InputStreamTransformer transformer, Charset encoding) {
80 this.artifact = artifact;
81 this.transformer = transformer;
82 this.encoding = encoding;
83 }
84
85 public AddArtifactTask(final Artifact artifact, Charset encoding) {
86 this(artifact, null, encoding);
87 }
88
89 public void execute(final Archiver archiver, final AssemblerConfigurationSource configSource)
90 throws ArchiveCreationException, AssemblyFormattingException {
91 if (artifactIsArchiverDestination(archiver)) {
92 artifact.setFile(moveArtifactSomewhereElse(configSource));
93 }
94
95 String destDirectory = AssemblyFormatUtils.getOutputDirectory(
96 outputDirectory,
97 configSource.getFinalName(),
98 configSource,
99 AssemblyFormatUtils.moduleProjectInterpolator(moduleProject),
100 AssemblyFormatUtils.artifactProjectInterpolator(project));
101
102 boolean fileModeSet = false;
103 boolean dirModeSet = false;
104
105 final int oldDirMode = archiver.getOverrideDirectoryMode();
106 final int oldFileMode = archiver.getOverrideFileMode();
107
108 if (fileMode != -1) {
109 archiver.setFileMode(fileMode);
110 fileModeSet = true;
111 }
112
113 if (directoryMode != -1) {
114 archiver.setDirectoryMode(directoryMode);
115 dirModeSet = true;
116 }
117 try {
118
119 if (unpack) {
120 unpacked(archiver, destDirectory);
121 } else {
122 asFile(archiver, configSource, destDirectory);
123 }
124 } finally {
125 if (dirModeSet) {
126 archiver.setDirectoryMode(oldDirMode);
127 }
128
129 if (fileModeSet) {
130 archiver.setFileMode(oldFileMode);
131 }
132 }
133 }
134
135 private void asFile(Archiver archiver, AssemblerConfigurationSource configSource, String destDirectory)
136 throws AssemblyFormattingException, ArchiveCreationException {
137 final String tempMapping = AssemblyFormatUtils.evaluateFileNameMapping(
138 outputFileNameMapping,
139 artifact,
140 configSource.getProject(),
141 moduleArtifact,
142 configSource,
143 AssemblyFormatUtils.moduleProjectInterpolator(moduleProject),
144 AssemblyFormatUtils.artifactProjectInterpolator(project));
145
146 final String outputLocation = destDirectory + tempMapping;
147
148 try {
149 final File artifactFile = artifact.getFile();
150
151 LOGGER.debug("Adding artifact: " + artifact.getId() + " with file: " + artifactFile
152 + " to assembly location: " + outputLocation + ".");
153
154 if (fileMode != -1) {
155 archiver.addFile(artifactFile, outputLocation, fileMode);
156 } else {
157 archiver.addFile(artifactFile, outputLocation);
158 }
159 } catch (final ArchiverException e) {
160 throw new ArchiveCreationException(
161 "Error adding file '" + artifact.getId() + "' to archive: " + e.getMessage(), e);
162 }
163 }
164
165 private void unpacked(Archiver archiver, String destDirectory) throws ArchiveCreationException {
166 String outputLocation = destDirectory;
167
168 if ((outputLocation.length() > 0) && !outputLocation.endsWith("/")) {
169 outputLocation += "/";
170 }
171
172 String[] includesArray = TypeConversionUtils.toStringArray(includes);
173 if (includesArray == null) {
174 includesArray = DEFAULT_INCLUDES_ARRAY;
175 }
176 final String[] excludesArray = TypeConversionUtils.toStringArray(excludes);
177
178 try {
179
180 final File artifactFile = artifact.getFile();
181 if (artifactFile == null) {
182 LOGGER.warn("Skipping artifact: " + artifact.getId()
183 + "; it does not have an associated file or directory.");
184 } else if (artifactFile.isDirectory()) {
185 LOGGER.debug("Adding artifact directory contents for: " + artifact + " to: " + outputLocation);
186
187 DefaultFileSet fs = DefaultFileSet.fileSet(artifactFile);
188 fs.setIncludes(includesArray);
189 fs.setExcludes(excludesArray);
190 fs.setPrefix(outputLocation);
191 fs.setStreamTransformer(transformer);
192 fs.setUsingDefaultExcludes(usingDefaultExcludes);
193 archiver.addFileSet(fs);
194 } else {
195 LOGGER.debug("Unpacking artifact contents for: " + artifact + " to: " + outputLocation);
196 LOGGER.debug("includes:\n" + StringUtils.join(includesArray, "\n") + "\n");
197 LOGGER.debug("excludes:\n" + (excludesArray == null ? "none" : StringUtils.join(excludesArray, "\n"))
198 + "\n");
199 DefaultArchivedFileSet afs = DefaultArchivedFileSet.archivedFileSet(artifactFile);
200 afs.setIncludes(includesArray);
201 afs.setExcludes(excludesArray);
202 afs.setPrefix(outputLocation);
203 afs.setStreamTransformer(transformer);
204 afs.setUsingDefaultExcludes(usingDefaultExcludes);
205 archiver.addArchivedFileSet(afs, encoding);
206 }
207 } catch (final ArchiverException e) {
208 throw new ArchiveCreationException(
209 "Error adding file-set for '" + artifact.getId() + "' to archive: " + e.getMessage(), e);
210 }
211 }
212
213 private File moveArtifactSomewhereElse(AssemblerConfigurationSource configSource) throws ArchiveCreationException {
214 final File tempRoot = configSource.getTemporaryRootDirectory();
215 final File tempArtifactFile = new File(tempRoot, artifact.getFile().getName());
216
217 LOGGER.warn("Artifact: " + artifact.getId() + " references the same file as the assembly destination file. "
218 + "Moving it to a temporary location for inclusion.");
219 try {
220 FileUtils.copyFile(artifact.getFile(), tempArtifactFile);
221 } catch (final IOException e) {
222 throw new ArchiveCreationException(
223 "Error moving artifact file: '" + artifact.getFile() + "' to temporary location: "
224 + tempArtifactFile + ". Reason: " + e.getMessage(),
225 e);
226 }
227 return tempArtifactFile;
228 }
229
230 private boolean artifactIsArchiverDestination(Archiver archiver) {
231 return ((artifact.getFile() != null) && (archiver.getDestFile() != null))
232 && artifact.getFile().equals(archiver.getDestFile());
233 }
234
235 public void setDirectoryMode(final int directoryMode) {
236 this.directoryMode = directoryMode;
237 }
238
239 public void setFileMode(final int fileMode) {
240 this.fileMode = fileMode;
241 }
242
243 public void setExcludes(final List<String> excludes) {
244 this.excludes = excludes;
245 }
246
247 public void setUsingDefaultExcludes(boolean usingDefaultExcludes) {
248 this.usingDefaultExcludes = usingDefaultExcludes;
249 }
250
251 public void setIncludes(final List<String> includes) {
252 this.includes = includes;
253 }
254
255 public void setUnpack(final boolean unpack) {
256 this.unpack = unpack;
257 }
258
259 public void setProject(final MavenProject project) {
260 this.project = project;
261 }
262
263 public void setOutputDirectory(final String outputDirectory) {
264 this.outputDirectory = outputDirectory;
265 }
266
267 public void setFileNameMapping(final String outputFileNameMapping) {
268 this.outputFileNameMapping = outputFileNameMapping;
269 }
270
271 public void setOutputDirectory(final String outputDirectory, final String defaultOutputDirectory) {
272 setOutputDirectory(outputDirectory == null ? defaultOutputDirectory : outputDirectory);
273 }
274
275 public void setFileNameMapping(final String outputFileNameMapping, final String defaultOutputFileNameMapping) {
276 setFileNameMapping(outputFileNameMapping == null ? defaultOutputFileNameMapping : outputFileNameMapping);
277 }
278
279 public void setModuleProject(final MavenProject moduleProject) {
280 this.moduleProject = moduleProject;
281 }
282
283 public void setModuleArtifact(final Artifact moduleArtifact) {
284 this.moduleArtifact = moduleArtifact;
285 }
286 }