View Javadoc

1   package org.apache.maven.project.artifact;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.Collections;
27  import java.util.HashMap;
28  import java.util.LinkedHashMap;
29  import java.util.LinkedHashSet;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Properties;
33  import java.util.Set;
34  
35  import org.apache.maven.artifact.Artifact;
36  import org.apache.maven.artifact.factory.ArtifactFactory;
37  import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
38  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
39  import org.apache.maven.artifact.metadata.ResolutionGroup;
40  import org.apache.maven.artifact.repository.ArtifactRepository;
41  import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
42  import org.apache.maven.artifact.repository.metadata.Metadata;
43  import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
44  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
45  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
46  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
47  import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
48  import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
49  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
50  import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
51  import org.apache.maven.artifact.versioning.ArtifactVersion;
52  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
53  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
54  import org.apache.maven.artifact.versioning.VersionRange;
55  import org.apache.maven.model.Dependency;
56  import org.apache.maven.model.DependencyManagement;
57  import org.apache.maven.model.DistributionManagement;
58  import org.apache.maven.model.Exclusion;
59  import org.apache.maven.model.Relocation;
60  import org.apache.maven.model.building.ModelBuildingException;
61  import org.apache.maven.model.building.ModelBuildingRequest;
62  import org.apache.maven.model.building.ModelProblem;
63  import org.apache.maven.model.resolution.UnresolvableModelException;
64  import org.apache.maven.plugin.LegacySupport;
65  import org.apache.maven.project.DefaultProjectBuildingRequest;
66  import org.apache.maven.project.MavenProject;
67  import org.apache.maven.project.ProjectBuilder;
68  import org.apache.maven.project.ProjectBuildingException;
69  import org.apache.maven.project.ProjectBuildingRequest;
70  import org.apache.maven.properties.internal.EnvironmentUtils;
71  import org.apache.maven.repository.legacy.metadata.DefaultMetadataResolutionRequest;
72  import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
73  import org.codehaus.plexus.PlexusContainer;
74  import org.codehaus.plexus.component.annotations.Component;
75  import org.codehaus.plexus.component.annotations.Requirement;
76  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
77  import org.codehaus.plexus.logging.Logger;
78  import org.eclipse.aether.RepositorySystemSession;
79  import org.eclipse.aether.repository.RepositoryPolicy;
80  import org.eclipse.aether.transfer.ArtifactNotFoundException;
81  
82  /**
83   * @author Jason van Zyl
84   */
85  @Component( role = ArtifactMetadataSource.class, hint = "maven" )
86  public class MavenMetadataSource
87      implements ArtifactMetadataSource
88  {
89      @Requirement
90      private RepositoryMetadataManager repositoryMetadataManager;
91  
92      @Requirement
93      private ArtifactFactory repositorySystem;
94  
95      //TODO: This prevents a cycle in the composition which shows us another problem we need to deal with.
96      //@Requirement
97      private ProjectBuilder projectBuilder;
98  
99      @Requirement
100     private PlexusContainer container;
101 
102     @Requirement
103     private Logger logger;
104 
105     @Requirement
106     private MavenMetadataCache cache;
107 
108     @Requirement
109     private LegacySupport legacySupport;
110 
111     private void injectSession( MetadataResolutionRequest request )
112     {
113         RepositorySystemSession session = legacySupport.getRepositorySession();
114 
115         if ( session != null )
116         {
117             request.setOffline( session.isOffline() );
118             request.setForceUpdate( RepositoryPolicy.UPDATE_POLICY_ALWAYS.equals( session.getUpdatePolicy() ) );
119         }
120     }
121 
122     public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
123                                      List<ArtifactRepository> remoteRepositories )
124         throws ArtifactMetadataRetrievalException
125     {
126         return retrieve( artifact, localRepository, remoteRepositories, false );
127     }
128 
129     public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository,
130                                      List<ArtifactRepository> remoteRepositories, boolean resolveManagedVersions )
131         throws ArtifactMetadataRetrievalException
132     {
133         MetadataResolutionRequest request = new DefaultMetadataResolutionRequest();
134         injectSession( request );
135         request.setArtifact( artifact );
136         request.setLocalRepository( localRepository );
137         request.setRemoteRepositories( remoteRepositories );
138         request.setResolveManagedVersions( resolveManagedVersions );
139         return retrieve( request );
140     }
141 
142     public ResolutionGroup retrieve( MetadataResolutionRequest request )
143         throws ArtifactMetadataRetrievalException
144     {
145         Artifact artifact = request.getArtifact();
146 
147         //
148         // If we have a system scoped artifact then we do not want any searching in local or remote repositories
149         // and we want artifact resolution to only return the system scoped artifact itself.
150         //
151         if ( artifact.getScope() != null && artifact.getScope().equals( Artifact.SCOPE_SYSTEM ) )
152         {
153             return new ResolutionGroup( null, null, null );
154         }
155 
156         ResolutionGroup cached =
157             cache.get( artifact, request.isResolveManagedVersions(), request.getLocalRepository(),
158                        request.getRemoteRepositories() );
159 
160         if ( cached != null )
161         {
162             // if the POM has no file, we cached a missing artifact, only return the cached data if no update forced
163             if ( !request.isForceUpdate() || hasFile( cached.getPomArtifact() ) )
164             {
165                 return cached;
166             }
167         }
168 
169         List<Dependency> dependencies;
170 
171         List<Dependency> managedDependencies = null;
172 
173         List<ArtifactRepository> pomRepositories = null;
174 
175         Artifact pomArtifact;
176 
177         Artifact relocatedArtifact = null;
178 
179         //TODO: Not even sure this is really required as the project will be cached in the builder, we'll see this
180         // is currently the biggest hotspot
181         if ( artifact instanceof ArtifactWithDependencies )
182         {
183             pomArtifact = artifact;
184 
185             dependencies = ( (ArtifactWithDependencies) artifact ).getDependencies();
186 
187             managedDependencies = ( (ArtifactWithDependencies) artifact ).getManagedDependencies();
188         }
189         else
190         {
191             ProjectRelocation rel = retrieveRelocatedProject( artifact, request );
192 
193             if ( rel == null )
194             {
195                 return null;
196             }
197 
198             pomArtifact = rel.pomArtifact;
199 
200             relocatedArtifact = rel.relocatedArtifact;
201 
202             if ( rel.project == null )
203             {
204                 // When this happens we have a Maven 1.x POM, or some invalid POM. 
205                 // It should have never found its way into Maven 2.x repository but it did.
206                 dependencies = Collections.emptyList();
207             }
208             else
209             {
210                 dependencies = rel.project.getDependencies();
211 
212                 DependencyManagement depMngt = rel.project.getDependencyManagement();
213                 managedDependencies = ( depMngt != null ) ? depMngt.getDependencies() : null;
214 
215                 pomRepositories = rel.project.getRemoteArtifactRepositories();
216             }
217         }
218 
219         Set<Artifact> artifacts = Collections.<Artifact>emptySet();
220 
221         if ( !artifact.getArtifactHandler().isIncludesDependencies() )
222         {
223             artifacts = new LinkedHashSet<Artifact>();
224 
225             for ( Dependency dependency : dependencies )
226             {
227                 Artifact dependencyArtifact = createDependencyArtifact( dependency, artifact, pomArtifact );
228 
229                 if ( dependencyArtifact != null )
230                 {
231                     artifacts.add( dependencyArtifact );
232                 }
233             }
234         }
235 
236         Map<String, Artifact> managedVersions = null;
237 
238         if ( managedDependencies != null && request.isResolveManagedVersions() )
239         {
240             managedVersions = new HashMap<String, Artifact>();
241 
242             for ( Dependency managedDependency : managedDependencies )
243             {
244                 Artifact managedArtifact = createDependencyArtifact( managedDependency, null, pomArtifact );
245 
246                 managedVersions.put( managedDependency.getManagementKey(), managedArtifact );
247             }
248         }
249 
250         List<ArtifactRepository> aggregatedRepositories =
251             aggregateRepositories( request.getRemoteRepositories(), pomRepositories );
252 
253         ResolutionGroup result =
254             new ResolutionGroup( pomArtifact, relocatedArtifact, artifacts, managedVersions, aggregatedRepositories );
255 
256         cache.put( artifact, request.isResolveManagedVersions(), request.getLocalRepository(),
257                    request.getRemoteRepositories(), result );
258 
259         return result;
260     }
261 
262     private boolean hasFile( Artifact artifact )
263     {
264         return artifact != null && artifact.getFile() != null && artifact.getFile().exists();
265     }
266 
267     private List<ArtifactRepository> aggregateRepositories( List<ArtifactRepository> requestRepositories,
268                                                             List<ArtifactRepository> pomRepositories )
269     {
270         List<ArtifactRepository> repositories = requestRepositories;
271 
272         if ( pomRepositories != null && !pomRepositories.isEmpty() )
273         {
274             Map<String, ArtifactRepository> repos = new LinkedHashMap<String, ArtifactRepository>();
275 
276             for ( ArtifactRepository repo : requestRepositories )
277             {
278                 if ( !repos.containsKey( repo.getId() ) )
279                 {
280                     repos.put( repo.getId(), repo );
281                 }
282             }
283 
284             for ( ArtifactRepository repo : pomRepositories )
285             {
286                 if ( !repos.containsKey( repo.getId() ) )
287                 {
288                     repos.put( repo.getId(), repo );
289                 }
290             }
291 
292             repositories = new ArrayList<ArtifactRepository>( repos.values() );
293         }
294 
295         return repositories;
296     }
297 
298     private Artifact createDependencyArtifact( Dependency dependency, Artifact owner, Artifact pom )
299         throws ArtifactMetadataRetrievalException
300     {
301         try
302         {
303             String inheritedScope = ( owner != null ) ? owner.getScope() : null;
304 
305             ArtifactFilter inheritedFilter = ( owner != null ) ? owner.getDependencyFilter() : null;
306 
307             return createDependencyArtifact( repositorySystem, dependency, inheritedScope, inheritedFilter );
308         }
309         catch ( InvalidVersionSpecificationException e )
310         {
311             throw new ArtifactMetadataRetrievalException( "Invalid version for dependency "
312                 + dependency.getManagementKey() + ": " + e.getMessage(), e, pom );
313         }
314     }
315 
316     private static Artifact createDependencyArtifact( ArtifactFactory factory, Dependency dependency,
317                                                       String inheritedScope, ArtifactFilter inheritedFilter )
318         throws InvalidVersionSpecificationException
319     {
320         String effectiveScope = getEffectiveScope( dependency.getScope(), inheritedScope );
321 
322         if ( effectiveScope == null )
323         {
324             return null;
325         }
326 
327         VersionRange versionRange = VersionRange.createFromVersionSpec( dependency.getVersion() );
328 
329         Artifact dependencyArtifact =
330             factory.createDependencyArtifact( dependency.getGroupId(), dependency.getArtifactId(), versionRange,
331                                               dependency.getType(), dependency.getClassifier(), effectiveScope,
332                                               dependency.isOptional() );
333 
334         ArtifactFilter dependencyFilter = inheritedFilter;
335 
336         if ( dependencyFilter != null && !dependencyFilter.include( dependencyArtifact ) )
337         {
338             return null;
339         }
340 
341         if ( Artifact.SCOPE_SYSTEM.equals( effectiveScope ) )
342         {
343             dependencyArtifact.setFile( new File( dependency.getSystemPath() ) );
344         }
345 
346         dependencyArtifact.setDependencyFilter( createDependencyFilter( dependency, dependencyFilter ) );
347 
348         return dependencyArtifact;
349     }
350 
351     private static String getEffectiveScope( String originalScope, String inheritedScope )
352     {
353         String effectiveScope = Artifact.SCOPE_RUNTIME;
354 
355         if ( originalScope == null )
356         {
357             originalScope = Artifact.SCOPE_COMPILE;
358         }
359 
360         if ( inheritedScope == null )
361         {
362             // direct dependency retains its scope
363             effectiveScope = originalScope;
364         }
365         else if ( Artifact.SCOPE_TEST.equals( originalScope ) || Artifact.SCOPE_PROVIDED.equals( originalScope ) )
366         {
367             // test and provided are not transitive, so exclude them
368             effectiveScope = null;
369         }
370         else if ( Artifact.SCOPE_SYSTEM.equals( originalScope ) )
371         {
372             // system scope come through unchanged...
373             effectiveScope = Artifact.SCOPE_SYSTEM;
374         }
375         else if ( Artifact.SCOPE_COMPILE.equals( originalScope ) && Artifact.SCOPE_COMPILE.equals( inheritedScope ) )
376         {
377             // added to retain compile scope. Remove if you want compile inherited as runtime
378             effectiveScope = Artifact.SCOPE_COMPILE;
379         }
380         else if ( Artifact.SCOPE_TEST.equals( inheritedScope ) )
381         {
382             effectiveScope = Artifact.SCOPE_TEST;
383         }
384         else if ( Artifact.SCOPE_PROVIDED.equals( inheritedScope ) )
385         {
386             effectiveScope = Artifact.SCOPE_PROVIDED;
387         }
388 
389         return effectiveScope;
390     }
391 
392     private static ArtifactFilter createDependencyFilter( Dependency dependency, ArtifactFilter inheritedFilter )
393     {
394         ArtifactFilter effectiveFilter = inheritedFilter;
395 
396         if ( !dependency.getExclusions().isEmpty() )
397         {
398             List<String> exclusions = new ArrayList<String>();
399 
400             for ( Exclusion e : dependency.getExclusions() )
401             {
402                 exclusions.add( e.getGroupId() + ':' + e.getArtifactId() );
403             }
404 
405             effectiveFilter = new ExcludesArtifactFilter( exclusions );
406 
407             if ( inheritedFilter != null )
408             {
409                 effectiveFilter = new AndArtifactFilter( Arrays.asList( inheritedFilter, effectiveFilter ) );
410             }
411         }
412 
413         return effectiveFilter;
414     }
415 
416     public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository,
417                                                             List<ArtifactRepository> remoteRepositories )
418         throws ArtifactMetadataRetrievalException
419     {
420         MetadataResolutionRequest request = new DefaultMetadataResolutionRequest();
421         injectSession( request );
422         request.setArtifact( artifact );
423         request.setLocalRepository( localRepository );
424         request.setRemoteRepositories( remoteRepositories );
425         return retrieveAvailableVersions( request );
426     }
427 
428     public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request )
429         throws ArtifactMetadataRetrievalException
430     {
431         RepositoryMetadata metadata = new ArtifactRepositoryMetadata( request.getArtifact() );
432 
433         try
434         {
435             repositoryMetadataManager.resolve( metadata, request );
436         }
437         catch ( RepositoryMetadataResolutionException e )
438         {
439             throw new ArtifactMetadataRetrievalException( e.getMessage(), e, request.getArtifact() );
440         }
441 
442         List<String> availableVersions = request.getLocalRepository().findVersions( request.getArtifact() );
443 
444         return retrieveAvailableVersionsFromMetadata( metadata.getMetadata(), availableVersions );
445     }
446 
447     public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( Artifact artifact,
448                                                                                     ArtifactRepository localRepository,
449                                                                                     ArtifactRepository deploymentRepository )
450         throws ArtifactMetadataRetrievalException
451     {
452         RepositoryMetadata metadata = new ArtifactRepositoryMetadata( artifact );
453 
454         try
455         {
456             repositoryMetadataManager.resolveAlways( metadata, localRepository, deploymentRepository );
457         }
458         catch ( RepositoryMetadataResolutionException e )
459         {
460             throw new ArtifactMetadataRetrievalException( e.getMessage(), e, artifact );
461         }
462 
463         List<String> availableVersions = localRepository.findVersions( artifact );
464 
465         return retrieveAvailableVersionsFromMetadata( metadata.getMetadata(), availableVersions );
466     }
467 
468     private List<ArtifactVersion> retrieveAvailableVersionsFromMetadata( Metadata repoMetadata,
469                                                                          List<String> availableVersions )
470     {
471         Collection<String> versions = new LinkedHashSet<String>();
472 
473         if ( ( repoMetadata != null ) && ( repoMetadata.getVersioning() != null ) )
474         {
475             versions.addAll( repoMetadata.getVersioning().getVersions() );
476         }
477 
478         versions.addAll( availableVersions );
479 
480         List<ArtifactVersion> artifactVersions = new ArrayList<ArtifactVersion>( versions.size() );
481 
482         for ( String version : versions )
483         {
484             artifactVersions.add( new DefaultArtifactVersion( version ) );
485         }
486 
487         return artifactVersions;
488     }
489 
490     // USED BY MAVEN ASSEMBLY PLUGIN
491     @Deprecated
492     public static Set<Artifact> createArtifacts( ArtifactFactory artifactFactory, List<Dependency> dependencies,
493                                                  String inheritedScope, ArtifactFilter dependencyFilter,
494                                                  MavenProject project )
495         throws InvalidDependencyVersionException
496     {
497         Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
498 
499         for ( Dependency d : dependencies )
500         {
501             Artifact dependencyArtifact;
502             try
503             {
504                 dependencyArtifact = createDependencyArtifact( artifactFactory, d, inheritedScope, dependencyFilter );
505             }
506             catch ( InvalidVersionSpecificationException e )
507             {
508                 throw new InvalidDependencyVersionException( project.getId(), d, project.getFile(), e );
509             }
510 
511             if ( dependencyArtifact != null )
512             {
513                 artifacts.add( dependencyArtifact );
514             }
515         }
516 
517         return artifacts;
518     }
519 
520     private ProjectBuilder getProjectBuilder()
521     {
522         if ( projectBuilder != null )
523         {
524             return projectBuilder;
525         }
526 
527         try
528         {
529             projectBuilder = container.lookup( ProjectBuilder.class );
530         }
531         catch ( ComponentLookupException e )
532         {
533             // Won't happen
534         }
535 
536         return projectBuilder;
537     }
538 
539     private ProjectRelocation retrieveRelocatedProject( Artifact artifact, MetadataResolutionRequest repositoryRequest )
540         throws ArtifactMetadataRetrievalException
541     {
542         MavenProject project;
543 
544         Artifact pomArtifact;
545         Artifact relocatedArtifact = null;
546         boolean done = false;
547         do
548         {
549             project = null;
550 
551             pomArtifact =
552                 repositorySystem.createProjectArtifact( artifact.getGroupId(),
553                                                         artifact.getArtifactId(),
554                                                         artifact.getVersion(), artifact.getScope() );
555 
556             if ( "pom".equals( artifact.getType() ) )
557             {
558                 pomArtifact.setFile( artifact.getFile() );
559             }
560 
561             if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
562             {
563                 done = true;
564             }
565             else
566             {
567                 try
568                 {
569                     ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
570                     configuration.setLocalRepository( repositoryRequest.getLocalRepository() );
571                     configuration.setRemoteRepositories( repositoryRequest.getRemoteRepositories() );
572                     configuration.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
573                     configuration.setProcessPlugins( false );
574                     configuration.setRepositoryMerging( ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT );
575                     configuration.setSystemProperties( getSystemProperties() );
576                     configuration.setRepositorySession( legacySupport.getRepositorySession() );
577 
578                     project = getProjectBuilder().build( pomArtifact, configuration ).getProject();
579                 }
580                 catch ( ProjectBuildingException e )
581                 {
582                     ModelProblem missingParentPom = hasMissingParentPom( e );
583                     if ( missingParentPom != null )
584                     {
585                         throw new ArtifactMetadataRetrievalException( "Failed to process POM for "
586                             + artifact.getId() + ": " + missingParentPom.getMessage(),
587                                                                       missingParentPom.getException(),
588                                                                       artifact );
589                     }
590 
591                     String message;
592 
593                     if ( isMissingPom( e ) )
594                     {
595                         message = "Missing POM for " + artifact.getId();
596                     }
597                     else if ( isNonTransferrablePom( e ) )
598                     {
599                         throw new ArtifactMetadataRetrievalException( "Failed to retrieve POM for "
600                             + artifact.getId() + ": " + e.getCause().getMessage(), e.getCause(),
601                                                                       artifact );
602                     }
603                     else
604                     {
605                         message =
606                             "Invalid POM for " + artifact.getId()
607                                 + ", transitive dependencies (if any) will not be available"
608                                 + ", enable debug logging for more details";
609                     }
610 
611                     if ( logger.isDebugEnabled() )
612                     {
613                         message += ": " + e.getMessage();
614                     }
615 
616                     logger.warn( message );
617                 }
618 
619                 if ( project != null )
620                 {
621                     Relocation relocation = null;
622 
623                     DistributionManagement distMgmt = project.getDistributionManagement();
624                     if ( distMgmt != null )
625                     {
626                         relocation = distMgmt.getRelocation();
627 
628                         artifact.setDownloadUrl( distMgmt.getDownloadUrl() );
629                         pomArtifact.setDownloadUrl( distMgmt.getDownloadUrl() );
630                     }
631 
632                     if ( relocation != null )
633                     {
634                         if ( relocation.getGroupId() != null )
635                         {
636                             artifact.setGroupId( relocation.getGroupId() );
637                             relocatedArtifact = artifact;
638                             project.setGroupId( relocation.getGroupId() );
639                         }
640                         if ( relocation.getArtifactId() != null )
641                         {
642                             artifact.setArtifactId( relocation.getArtifactId() );
643                             relocatedArtifact = artifact;
644                             project.setArtifactId( relocation.getArtifactId() );
645                         }
646                         if ( relocation.getVersion() != null )
647                         {
648                             // note: see MNG-3454. This causes a problem, but fixing it may break more.
649                             artifact.setVersionRange( VersionRange.createFromVersion( relocation.getVersion() ) );
650                             relocatedArtifact = artifact;
651                             project.setVersion( relocation.getVersion() );
652                         }
653 
654                         if ( artifact.getDependencyFilter() != null
655                             && !artifact.getDependencyFilter().include( artifact ) )
656                         {
657                             return null;
658                         }
659 
660                         // MNG-2861: the artifact data has changed. If the available versions where previously
661                         // retrieved, we need to update it.
662                         // TODO: shouldn't the versions be merged across relocations?
663                         List<ArtifactVersion> available = artifact.getAvailableVersions();
664                         if ( available != null && !available.isEmpty() )
665                         {
666                             MetadataResolutionRequest metadataRequest =
667                                 new DefaultMetadataResolutionRequest( repositoryRequest );
668                             metadataRequest.setArtifact( artifact );
669                             available = retrieveAvailableVersions( metadataRequest );
670                             artifact.setAvailableVersions( available );
671                         }
672 
673                         String message =
674                             "\n  This artifact has been relocated to " + artifact.getGroupId() + ":"
675                                 + artifact.getArtifactId() + ":" + artifact.getVersion() + ".\n";
676 
677                         if ( relocation.getMessage() != null )
678                         {
679                             message += "  " + relocation.getMessage() + "\n";
680                         }
681 
682                         if ( artifact.getDependencyTrail() != null && artifact.getDependencyTrail().size() == 1 )
683                         {
684                             logger.warn( "While downloading " + pomArtifact.getGroupId() + ":"
685                                 + pomArtifact.getArtifactId() + ":" + pomArtifact.getVersion() + message + "\n" );
686                         }
687                         else
688                         {
689                             logger.debug( "While downloading " + pomArtifact.getGroupId() + ":"
690                                 + pomArtifact.getArtifactId() + ":" + pomArtifact.getVersion() + message + "\n" );
691                         }
692                     }
693                     else
694                     {
695                         done = true;
696                     }
697                 }
698                 else
699                 {
700                     done = true;
701                 }
702             }
703         }
704         while ( !done );
705 
706         ProjectRelocation rel = new ProjectRelocation();
707         rel.project = project;
708         rel.pomArtifact = pomArtifact;
709         rel.relocatedArtifact = relocatedArtifact;
710 
711         return rel;
712     }
713 
714     private ModelProblem hasMissingParentPom( ProjectBuildingException e )
715     {
716         if ( e.getCause() instanceof ModelBuildingException )
717         {
718             ModelBuildingException mbe = (ModelBuildingException) e.getCause();
719             for ( ModelProblem problem : mbe.getProblems() )
720             {
721                 if ( problem.getException() instanceof UnresolvableModelException )
722                 {
723                     return problem;
724                 }
725             }
726 
727         }
728         return null;
729     }
730 
731     private boolean isMissingPom( Exception e )
732     {
733         if ( e.getCause() instanceof MultipleArtifactsNotFoundException )
734         {
735             return true;
736         }
737         return e.getCause() instanceof org.eclipse.aether.resolution.ArtifactResolutionException
738             && e.getCause().getCause() instanceof ArtifactNotFoundException;
739     }
740 
741     private boolean isNonTransferrablePom( Exception e )
742     {
743         if ( e.getCause() instanceof ArtifactResolutionException )
744         {
745             return true;
746         }
747         return e.getCause() instanceof org.eclipse.aether.resolution.ArtifactResolutionException
748             && !( e.getCause().getCause() instanceof ArtifactNotFoundException );
749     }
750 
751     private Properties getSystemProperties()
752     {
753         Properties props = new Properties();
754 
755         EnvironmentUtils.addEnvVars( props );
756 
757         props.putAll( System.getProperties() );
758 
759         return props;
760     }
761 
762     private static final class ProjectRelocation
763     {
764         private MavenProject project;
765 
766         private Artifact pomArtifact;
767 
768         private Artifact relocatedArtifact;
769     }
770 
771 }