1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.dependency;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.lang.reflect.Field;
24 import java.util.List;
25 import org.apache.maven.artifact.Artifact;
26 import org.apache.maven.artifact.repository.ArtifactRepository;
27 import org.apache.maven.execution.MavenSession;
28 import org.apache.maven.plugin.AbstractMojo;
29 import org.apache.maven.plugin.MojoExecutionException;
30 import org.apache.maven.plugin.MojoFailureException;
31 import org.apache.maven.plugins.annotations.Component;
32 import org.apache.maven.plugins.annotations.Parameter;
33 import org.apache.maven.plugins.dependency.utils.DependencySilentLog;
34 import org.apache.maven.project.DefaultProjectBuildingRequest;
35 import org.apache.maven.project.MavenProject;
36 import org.apache.maven.project.ProjectBuildingRequest;
37 import org.codehaus.plexus.archiver.ArchiverException;
38 import org.codehaus.plexus.archiver.UnArchiver;
39 import org.codehaus.plexus.archiver.manager.ArchiverManager;
40 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
41 import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
42 import org.codehaus.plexus.components.io.filemappers.FileMapper;
43 import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector;
44 import org.codehaus.plexus.util.FileUtils;
45 import org.codehaus.plexus.util.ReflectionUtils;
46 import org.codehaus.plexus.util.StringUtils;
47 import org.sonatype.plexus.build.incremental.BuildContext;
48
49
50
51
52 public abstract class AbstractDependencyMojo extends AbstractMojo {
53
54
55
56 @Component
57 private ArchiverManager archiverManager;
58
59
60
61
62 @Component
63 private BuildContext buildContext;
64
65
66
67
68
69
70
71 @Parameter(defaultValue = "false")
72 private boolean skipDuringIncrementalBuild;
73
74
75
76
77
78
79
80
81
82 @Parameter(property = "dependency.useJvmChmod", defaultValue = "true")
83 private boolean useJvmChmod = true;
84
85
86
87
88
89
90 @Parameter(property = "dependency.ignorePermissions", defaultValue = "false")
91 private boolean ignorePermissions;
92
93
94
95
96 @Parameter(defaultValue = "${project}", readonly = true, required = true)
97 private MavenProject project;
98
99
100
101
102 @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true)
103 private List<ArtifactRepository> remoteRepositories;
104
105
106
107
108 @Parameter(defaultValue = "${project.pluginArtifactRepositories}", readonly = true, required = true)
109 private List<ArtifactRepository> remotePluginRepositories;
110
111
112
113
114 @Parameter(defaultValue = "${reactorProjects}", readonly = true)
115 protected List<MavenProject> reactorProjects;
116
117
118
119
120 @Parameter(defaultValue = "${session}", readonly = true, required = true)
121 protected MavenSession session;
122
123
124
125
126
127
128 @Parameter(property = "silent", defaultValue = "false")
129 private boolean silent;
130
131
132
133
134
135
136 @Parameter(property = "outputAbsoluteArtifactFilename", defaultValue = "false")
137 protected boolean outputAbsoluteArtifactFilename;
138
139
140
141
142
143
144 @Parameter(property = "mdep.skip", defaultValue = "false")
145 private boolean skip;
146
147
148
149
150
151
152 @Override
153 public final void execute() throws MojoExecutionException, MojoFailureException {
154 if (isSkip()) {
155 getLog().info("Skipping plugin execution");
156 return;
157 }
158
159 doExecute();
160 }
161
162
163
164
165
166 protected abstract void doExecute() throws MojoExecutionException, MojoFailureException;
167
168
169
170
171 public ArchiverManager getArchiverManager() {
172 return this.archiverManager;
173 }
174
175
176
177
178
179
180
181
182 protected void copyFile(File artifact, File destFile) throws MojoExecutionException {
183 try {
184 getLog().info("Copying "
185 + (this.outputAbsoluteArtifactFilename ? artifact.getAbsolutePath() : artifact.getName()) + " to "
186 + destFile);
187
188 if (artifact.isDirectory()) {
189
190 throw new MojoExecutionException("Artifact has not been packaged yet. When used on reactor artifact, "
191 + "copy should be executed after packaging: see MDEP-187.");
192 }
193
194 FileUtils.copyFile(artifact, destFile);
195 buildContext.refresh(destFile);
196 } catch (IOException e) {
197 throw new MojoExecutionException("Error copying artifact from " + artifact + " to " + destFile, e);
198 }
199 }
200
201
202
203
204
205
206
207
208
209 protected void unpack(Artifact artifact, File location, String encoding, FileMapper[] fileMappers)
210 throws MojoExecutionException {
211 unpack(artifact, location, null, null, encoding, fileMappers);
212 }
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 protected void unpack(
229 Artifact artifact,
230 File location,
231 String includes,
232 String excludes,
233 String encoding,
234 FileMapper[] fileMappers)
235 throws MojoExecutionException {
236 unpack(artifact, artifact.getType(), location, includes, excludes, encoding, fileMappers);
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250 protected void unpack(
251 Artifact artifact,
252 String type,
253 File location,
254 String includes,
255 String excludes,
256 String encoding,
257 FileMapper[] fileMappers)
258 throws MojoExecutionException {
259 File file = artifact.getFile();
260 try {
261 logUnpack(file, location, includes, excludes);
262
263 location.mkdirs();
264 if (!location.exists()) {
265 throw new MojoExecutionException(
266 "Location to write unpacked files to could not be created: " + location);
267 }
268
269 if (file.isDirectory()) {
270
271 throw new MojoExecutionException("Artifact has not been packaged yet. When used on reactor artifact, "
272 + "unpack should be executed after packaging: see MDEP-98.");
273 }
274
275 UnArchiver unArchiver;
276
277 try {
278 unArchiver = archiverManager.getUnArchiver(type);
279 getLog().debug("Found unArchiver by type: " + unArchiver);
280 } catch (NoSuchArchiverException e) {
281 unArchiver = archiverManager.getUnArchiver(file);
282 getLog().debug("Found unArchiver by extension: " + unArchiver);
283 }
284
285 if (encoding != null && unArchiver instanceof ZipUnArchiver) {
286 ((ZipUnArchiver) unArchiver).setEncoding(encoding);
287 getLog().info("Unpacks '" + type + "' with encoding '" + encoding + "'.");
288 }
289
290 unArchiver.setIgnorePermissions(ignorePermissions);
291
292 unArchiver.setSourceFile(file);
293
294 unArchiver.setDestDirectory(location);
295
296 if (StringUtils.isNotEmpty(excludes) || StringUtils.isNotEmpty(includes)) {
297
298
299
300 IncludeExcludeFileSelector[] selectors =
301 new IncludeExcludeFileSelector[] {new IncludeExcludeFileSelector()};
302
303 if (StringUtils.isNotEmpty(excludes)) {
304 selectors[0].setExcludes(excludes.split(","));
305 }
306
307 if (StringUtils.isNotEmpty(includes)) {
308 selectors[0].setIncludes(includes.split(","));
309 }
310
311 unArchiver.setFileSelectors(selectors);
312 }
313 if (this.silent) {
314 silenceUnarchiver(unArchiver);
315 }
316
317 unArchiver.setFileMappers(fileMappers);
318
319 unArchiver.extract();
320 } catch (NoSuchArchiverException e) {
321 throw new MojoExecutionException("Unknown archiver type", e);
322 } catch (ArchiverException e) {
323 throw new MojoExecutionException("Error unpacking file: " + file + " to: " + location, e);
324 }
325 buildContext.refresh(location);
326 }
327
328 private void silenceUnarchiver(UnArchiver unArchiver) {
329
330 try {
331 Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses("logger", unArchiver.getClass());
332
333 field.setAccessible(true);
334
335 field.set(unArchiver, this.getLog());
336 } catch (Exception e) {
337
338 }
339 }
340
341
342
343
344
345 public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest() {
346 return newProjectBuildingRequest(remoteRepositories);
347 }
348
349
350
351
352
353 protected ProjectBuildingRequest newResolvePluginProjectBuildingRequest() {
354 return newProjectBuildingRequest(remotePluginRepositories);
355 }
356
357 private ProjectBuildingRequest newProjectBuildingRequest(List<ArtifactRepository> repositories) {
358 ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
359
360 buildingRequest.setRemoteRepositories(repositories);
361
362 return buildingRequest;
363 }
364
365
366
367
368 public MavenProject getProject() {
369 return this.project;
370 }
371
372
373
374
375 public void setArchiverManager(ArchiverManager archiverManager) {
376 this.archiverManager = archiverManager;
377 }
378
379
380
381
382 public boolean isUseJvmChmod() {
383 return useJvmChmod;
384 }
385
386
387
388
389 public void setUseJvmChmod(boolean useJvmChmod) {
390 this.useJvmChmod = useJvmChmod;
391 }
392
393
394
395
396 public boolean isSkip() {
397 if (skipDuringIncrementalBuild && buildContext.isIncremental()) {
398 return true;
399 }
400 return skip;
401 }
402
403
404
405
406 public void setSkip(boolean skip) {
407 this.skip = skip;
408 }
409
410
411
412
413 protected final boolean isSilent() {
414 return silent;
415 }
416
417
418
419
420 public void setSilent(boolean silent) {
421 this.silent = silent;
422 if (silent) {
423 setLog(new DependencySilentLog());
424 }
425 }
426
427 private void logUnpack(File file, File location, String includes, String excludes) {
428 if (!getLog().isInfoEnabled()) {
429 return;
430 }
431
432 StringBuilder msg = new StringBuilder();
433 msg.append("Unpacking ");
434 msg.append(file);
435 msg.append(" to ");
436 msg.append(location);
437
438 if (includes != null && excludes != null) {
439 msg.append(" with includes \"");
440 msg.append(includes);
441 msg.append("\" and excludes \"");
442 msg.append(excludes);
443 msg.append("\"");
444 } else if (includes != null) {
445 msg.append(" with includes \"");
446 msg.append(includes);
447 msg.append("\"");
448 } else if (excludes != null) {
449 msg.append(" with excludes \"");
450 msg.append(excludes);
451 msg.append("\"");
452 }
453
454 getLog().info(msg.toString());
455 }
456 }