1 package org.apache.maven.plugins.invoker;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.LinkedHashSet;
29 import java.util.Map;
30
31 import org.apache.maven.artifact.Artifact;
32 import org.apache.maven.artifact.factory.ArtifactFactory;
33 import org.apache.maven.artifact.repository.ArtifactRepository;
34 import org.apache.maven.execution.MavenSession;
35 import org.apache.maven.model.Model;
36 import org.apache.maven.model.Parent;
37 import org.apache.maven.plugin.AbstractMojo;
38 import org.apache.maven.plugin.MojoExecutionException;
39 import org.apache.maven.plugins.annotations.Component;
40 import org.apache.maven.plugins.annotations.LifecyclePhase;
41 import org.apache.maven.plugins.annotations.Mojo;
42 import org.apache.maven.plugins.annotations.Parameter;
43 import org.apache.maven.plugins.annotations.ResolutionScope;
44 import org.apache.maven.project.MavenProject;
45 import org.apache.maven.project.ProjectBuildingRequest;
46 import org.apache.maven.shared.artifact.install.ArtifactInstaller;
47 import org.apache.maven.shared.dependencies.DefaultDependableCoordinate;
48 import org.apache.maven.shared.dependencies.resolve.DependencyResolver;
49 import org.apache.maven.shared.dependencies.resolve.DependencyResolverException;
50 import org.apache.maven.shared.repository.RepositoryManager;
51 import org.codehaus.plexus.util.FileUtils;
52
53
54
55
56
57
58
59
60
61
62
63
64 @Mojo( name = "install", defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST, requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true )
65
66 public class InstallMojo
67 extends AbstractMojo
68 {
69
70
71
72
73 @Component
74 private ArtifactInstaller installer;
75
76 @Component
77 private RepositoryManager repositoryManager;
78
79
80
81
82 @Component
83 private ArtifactFactory artifactFactory;
84
85
86
87 @Parameter( property = "localRepository", required = true, readonly = true )
88 private ArtifactRepository localRepository;
89
90
91
92
93
94
95
96 @Parameter( property = "invoker.localRepositoryPath",
97 defaultValue = "${session.localRepository.basedir}", required = true )
98 private File localRepositoryPath;
99
100
101
102
103 @Parameter( defaultValue = "${project}", readonly = true, required = true )
104 private MavenProject project;
105
106 @Parameter( defaultValue = "${session}", readonly = true, required = true )
107 private MavenSession session;
108
109
110
111
112 @Parameter( defaultValue = "${reactorProjects}", readonly = true )
113 private Collection<MavenProject> reactorProjects;
114
115
116
117
118
119
120
121 @Parameter( property = "invoker.skip", defaultValue = "false" )
122 private boolean skipInstallation;
123
124
125
126
127 private Collection<String> installedArtifacts;
128
129
130
131
132 private Collection<String> copiedArtifacts;
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154 @Parameter
155 private String[] extraArtifacts;
156
157
158
159 @Component
160 private DependencyResolver resolver;
161
162 private ProjectBuildingRequest projectBuildingRequest;
163
164
165
166
167
168
169 public void execute()
170 throws MojoExecutionException
171 {
172 if ( skipInstallation )
173 {
174 getLog().info( "Skipping artifact installation per configuration." );
175 return;
176 }
177
178 createTestRepository();
179
180 installedArtifacts = new HashSet<String>();
181 copiedArtifacts = new HashSet<String>();
182
183 installProjectDependencies( project, reactorProjects );
184 installProjectParents( project );
185 installProjectArtifacts( project );
186
187 installExtraArtifacts( extraArtifacts );
188 }
189
190
191
192
193
194
195
196
197
198
199 private void createTestRepository()
200 throws MojoExecutionException
201 {
202
203 if ( !localRepositoryPath.exists() && !localRepositoryPath.mkdirs() )
204 {
205 throw new MojoExecutionException( "Failed to create directory: " + localRepositoryPath );
206 }
207 projectBuildingRequest =
208 repositoryManager.setLocalRepositoryBasedir( session.getProjectBuildingRequest(), localRepositoryPath );
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223 private void installArtifact( File file, Artifact artifact )
224 throws MojoExecutionException
225 {
226 try
227 {
228 if ( file == null )
229 {
230 throw new IllegalStateException( "Artifact has no associated file: " + artifact.getId() );
231 }
232 if ( !file.isFile() )
233 {
234 throw new IllegalStateException( "Artifact is not fully assembled: " + file );
235 }
236
237 if ( installedArtifacts.add( artifact.getId() ) )
238 {
239 artifact.setFile( file );
240 installer.install( projectBuildingRequest, localRepositoryPath,
241 Collections.singletonList( artifact ) );
242 }
243 else
244 {
245 getLog().debug( "Not re-installing " + artifact + ", " + file );
246 }
247 }
248 catch ( Exception e )
249 {
250 throw new MojoExecutionException( "Failed to install artifact: " + artifact, e );
251 }
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265 private void copyArtifact( File file, Artifact artifact )
266 throws MojoExecutionException
267 {
268 try
269 {
270 if ( file == null )
271 {
272 throw new IllegalStateException( "Artifact has no associated file: " + artifact.getId() );
273 }
274 if ( !file.isFile() )
275 {
276 throw new IllegalStateException( "Artifact is not fully assembled: " + file );
277 }
278
279 if ( copiedArtifacts.add( artifact.getId() ) )
280 {
281 File destination =
282 new File( localRepositoryPath,
283 repositoryManager.getPathForLocalArtifact( projectBuildingRequest, artifact ) );
284
285 getLog().debug( "Installing " + file + " to " + destination );
286
287 copyFileIfDifferent( file, destination );
288
289 MetadataUtils.createMetadata( destination, artifact );
290 }
291 else
292 {
293 getLog().debug( "Not re-installing " + artifact + ", " + file );
294 }
295 }
296 catch ( Exception e )
297 {
298 throw new MojoExecutionException( "Failed to stage artifact: " + artifact, e );
299 }
300 }
301
302 private void copyFileIfDifferent( File src, File dst )
303 throws IOException
304 {
305 if ( src.lastModified() != dst.lastModified() || src.length() != dst.length() )
306 {
307 FileUtils.copyFile( src, dst );
308 dst.setLastModified( src.lastModified() );
309 }
310 }
311
312
313
314
315
316
317
318 private void installProjectArtifacts( MavenProject mvnProject )
319 throws MojoExecutionException
320 {
321 try
322 {
323
324 installProjectPom( mvnProject );
325
326
327 Artifact mainArtifact = mvnProject.getArtifact();
328 if ( mainArtifact.getFile() != null )
329 {
330 installArtifact( mainArtifact.getFile(), mainArtifact );
331 }
332
333
334 Collection<Artifact> attachedArtifacts = (Collection<Artifact>) mvnProject.getAttachedArtifacts();
335 for ( Artifact attachedArtifact : attachedArtifacts )
336 {
337 installArtifact( attachedArtifact.getFile(), attachedArtifact );
338 }
339 }
340 catch ( Exception e )
341 {
342 throw new MojoExecutionException( "Failed to install project artifacts: " + mvnProject, e );
343 }
344 }
345
346
347
348
349
350
351
352
353 private void installProjectParents( MavenProject mvnProject )
354 throws MojoExecutionException
355 {
356 try
357 {
358 for ( MavenProject parent = mvnProject.getParent(); parent != null; parent = parent.getParent() )
359 {
360 if ( parent.getFile() == null )
361 {
362 copyParentPoms( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
363 break;
364 }
365 installProjectPom( parent );
366 }
367 }
368 catch ( Exception e )
369 {
370 throw new MojoExecutionException( "Failed to install project parents: " + mvnProject, e );
371 }
372 }
373
374
375
376
377
378
379
380 private void installProjectPom( MavenProject mvnProject )
381 throws MojoExecutionException
382 {
383 try
384 {
385 Artifact pomArtifact = null;
386 if ( "pom".equals( mvnProject.getPackaging() ) )
387 {
388 pomArtifact = mvnProject.getArtifact();
389 }
390 if ( pomArtifact == null )
391 {
392 pomArtifact =
393 artifactFactory.createProjectArtifact( mvnProject.getGroupId(), mvnProject.getArtifactId(),
394 mvnProject.getVersion() );
395 }
396 installArtifact( mvnProject.getFile(), pomArtifact );
397 }
398 catch ( Exception e )
399 {
400 throw new MojoExecutionException( "Failed to install POM: " + mvnProject, e );
401 }
402 }
403
404
405
406
407
408
409
410
411
412 private void installProjectDependencies( MavenProject mvnProject, Collection<MavenProject> reactorProjects )
413 throws MojoExecutionException
414 {
415
416 boolean foundCurrent = false;
417
418
419 Collection<String> dependencyProjects = new LinkedHashSet<String>();
420
421
422 Map<String, MavenProject> projects = new HashMap<String, MavenProject>( reactorProjects.size() );
423 for ( MavenProject reactorProject : reactorProjects )
424 {
425 String projectId =
426 reactorProject.getGroupId() + ':' + reactorProject.getArtifactId() + ':' + reactorProject.getVersion();
427
428 projects.put( projectId, reactorProject );
429
430
431 foundCurrent |= ( mvnProject.equals( reactorProject ) );
432 if ( !foundCurrent )
433 {
434 dependencyProjects.add( projectId );
435 }
436 }
437
438
439 Collection<Artifact> artifacts = (Collection<Artifact>) mvnProject.getArtifacts();
440
441 Collection<Artifact> dependencyArtifacts = new LinkedHashSet<Artifact>();
442
443 for ( Artifact artifact : artifacts )
444 {
445
446 artifact.isSnapshot();
447
448 String projectId = artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion();
449
450 if ( !projects.containsKey( projectId ) )
451 {
452 dependencyArtifacts.add( artifact );
453 }
454 }
455
456
457 try
458 {
459
460 for ( Artifact artifact : dependencyArtifacts )
461 {
462 copyArtifact( artifact );
463 }
464
465
466 for ( String projectId : dependencyProjects )
467 {
468 MavenProject dependencyProject = projects.get( projectId );
469
470 installProjectArtifacts( dependencyProject );
471 installProjectParents( dependencyProject );
472 }
473 }
474 catch ( Exception e )
475 {
476 throw new MojoExecutionException( "Failed to install project dependencies: " + mvnProject, e );
477 }
478 }
479
480 private void copyArtifact( Artifact artifact )
481 throws MojoExecutionException
482 {
483 copyPoms( artifact );
484
485 Artifact depArtifact =
486 artifactFactory.createArtifactWithClassifier( artifact.getGroupId(), artifact.getArtifactId(),
487 artifact.getBaseVersion(), artifact.getType(),
488 artifact.getClassifier() );
489
490 File artifactFile = artifact.getFile();
491
492 copyArtifact( artifactFile, depArtifact );
493 }
494
495 private void copyPoms( Artifact artifact )
496 throws MojoExecutionException
497 {
498 Artifact pomArtifact =
499 artifactFactory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
500 artifact.getBaseVersion() );
501
502 File pomFile = new File( localRepository.getBasedir(), localRepository.pathOf( pomArtifact ) );
503
504 if ( pomFile.isFile() )
505 {
506 copyArtifact( pomFile, pomArtifact );
507 copyParentPoms( pomFile );
508 }
509 }
510
511
512
513
514
515
516
517 private void copyParentPoms( File pomFile )
518 throws MojoExecutionException
519 {
520 Model model = PomUtils.loadPom( pomFile );
521 Parent parent = model.getParent();
522 if ( parent != null )
523 {
524 copyParentPoms( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
525 }
526 }
527
528
529
530
531
532
533
534
535
536 private void copyParentPoms( String groupId, String artifactId, String version )
537 throws MojoExecutionException
538 {
539 Artifact pomArtifact = artifactFactory.createProjectArtifact( groupId, artifactId, version );
540
541 if ( installedArtifacts.contains( pomArtifact.getId() ) || copiedArtifacts.contains( pomArtifact.getId() ) )
542 {
543 getLog().debug( "Not re-installing " + pomArtifact );
544 return;
545 }
546
547 File pomFile = new File( localRepository.getBasedir(), localRepository.pathOf( pomArtifact ) );
548 if ( pomFile.isFile() )
549 {
550 copyArtifact( pomFile, pomArtifact );
551 copyParentPoms( pomFile );
552 }
553 }
554
555 private void installExtraArtifacts( String[] extraArtifacts )
556 throws MojoExecutionException
557 {
558 if ( extraArtifacts == null )
559 {
560 return;
561 }
562
563 for ( String extraArtifact : extraArtifacts )
564 {
565 String[] gav = extraArtifact.split( ":" );
566 if ( gav.length < 3 || gav.length > 5 )
567 {
568 throw new MojoExecutionException( "Invalid artifact " + extraArtifact );
569 }
570
571 String groupId = gav[0];
572 String artifactId = gav[1];
573 String version = gav[2];
574
575 String type = "jar";
576 if ( gav.length > 3 )
577 {
578 type = gav[3];
579 }
580
581 String classifier = null;
582 if ( gav.length == 5 )
583 {
584 classifier = gav[4];
585 }
586
587 DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate();
588 try
589 {
590 coordinate.setGroupId( groupId );
591 coordinate.setArtifactId( artifactId );
592 coordinate.setVersion( version );
593 coordinate.setType( type );
594 coordinate.setClassifier( classifier );
595
596 resolver.resolveDependencies( projectBuildingRequest, coordinate, null );
597 }
598 catch ( DependencyResolverException e )
599 {
600 throw new MojoExecutionException( "Unable to resolve dependencies for: " + coordinate, e );
601 }
602 }
603 }
604
605 }