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