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