View Javadoc
1   package org.apache.maven.plugin.surefire;
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 org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.factory.ArtifactFactory;
24  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
25  import org.apache.maven.artifact.repository.ArtifactRepository;
26  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
27  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
28  import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
29  import org.apache.maven.artifact.resolver.ArtifactResolver;
30  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
31  import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
32  import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
33  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
34  import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
35  import org.apache.maven.artifact.versioning.VersionRange;
36  import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
37  
38  import javax.annotation.Nonnull;
39  import javax.annotation.Nullable;
40  import java.util.Collections;
41  import java.util.LinkedHashSet;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.Set;
45  
46  import static java.util.Collections.singleton;
47  import static org.apache.maven.artifact.Artifact.SCOPE_TEST;
48  import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
49  
50  /**
51   * Does dependency resolution and artifact handling for the surefire plugin.
52   *
53   * @author Stephen Connolly
54   * @author Kristian Rosenvold
55   */
56  public class SurefireDependencyResolver
57  {
58  
59      private final ArtifactResolver artifactResolver;
60  
61      private final ArtifactFactory artifactFactory;
62  
63      private final ConsoleLogger log;
64  
65      private final ArtifactRepository localRepository;
66  
67      private final List<ArtifactRepository> remoteRepositories;
68  
69      private final ArtifactMetadataSource artifactMetadataSource;
70  
71      private final String pluginName;
72  
73      protected SurefireDependencyResolver( ArtifactResolver artifactResolver, ArtifactFactory artifactFactory,
74                                            ConsoleLogger log,
75                                            ArtifactRepository localRepository,
76                                            List<ArtifactRepository> remoteRepositories,
77                                            ArtifactMetadataSource artifactMetadataSource, String pluginName )
78      {
79          this.artifactResolver = artifactResolver;
80          this.artifactFactory = artifactFactory;
81          this.log = log;
82          this.localRepository = localRepository;
83          this.remoteRepositories = remoteRepositories;
84          this.artifactMetadataSource = artifactMetadataSource;
85          this.pluginName = pluginName;
86      }
87  
88  
89      public boolean isWithinVersionSpec( @Nullable Artifact artifact, @Nonnull String versionSpec )
90      {
91          if ( artifact == null )
92          {
93              return false;
94          }
95          try
96          {
97              VersionRange range = VersionRange.createFromVersionSpec( versionSpec );
98              try
99              {
100                 return range.containsVersion( artifact.getSelectedVersion() );
101             }
102             catch ( NullPointerException e )
103             {
104                 return range.containsVersion( new DefaultArtifactVersion( artifact.getBaseVersion() ) );
105             }
106         }
107         catch ( InvalidVersionSpecificationException e )
108         {
109             throw new RuntimeException( "Bug in plugin. Please report with stacktrace" );
110         }
111         catch ( OverConstrainedVersionException e )
112         {
113             throw new RuntimeException( "Bug in plugin. Please report with stacktrace" );
114         }
115     }
116 
117 
118     private ArtifactResolutionResult resolveArtifact( Artifact filteredArtifact, Artifact providerArtifact )
119         throws ArtifactResolutionException, ArtifactNotFoundException
120     {
121         ArtifactFilter filter = null;
122         if ( filteredArtifact != null )
123         {
124             filter = new ExcludesArtifactFilter(
125                 Collections.singletonList( filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId() ) );
126         }
127 
128         Artifact originatingArtifact = artifactFactory.createBuildArtifact( "dummy", "dummy", "1.0", "jar" );
129 
130         return artifactResolver.resolveTransitively( singleton( providerArtifact ), originatingArtifact,
131                                                      localRepository, remoteRepositories, artifactMetadataSource,
132                                                      filter );
133     }
134 
135     @Nonnull
136     @SuppressWarnings( "unchecked" )
137     public Set<Artifact> getProviderClasspath( String provider, String version, Artifact filteredArtifact )
138         throws ArtifactNotFoundException, ArtifactResolutionException
139     {
140         Artifact providerArtifact = artifactFactory.createDependencyArtifact( "org.apache.maven.surefire",
141                 provider, createFromVersion( version ), "jar", null, SCOPE_TEST );
142 
143         ArtifactResolutionResult result = resolveArtifact( filteredArtifact, providerArtifact );
144 
145         if ( log.isDebugEnabled() )
146         {
147             for ( Object o : result.getArtifacts() )
148             {
149                 Artifact artifact = (Artifact) o;
150                 String artifactPath = artifact.getFile().getAbsolutePath();
151                 String scope = artifact.getScope();
152                 log.debug( "Adding to " + pluginName + " test classpath: " + artifactPath + " Scope: " + scope );
153             }
154         }
155 
156         return result.getArtifacts();
157     }
158 
159     public Set<Artifact> addProviderToClasspath( Map<String, Artifact> pluginArtifactMap, Artifact surefireArtifact )
160         throws ArtifactResolutionException, ArtifactNotFoundException
161     {
162         Set<Artifact> providerArtifacts = new LinkedHashSet<Artifact>();
163         if ( surefireArtifact != null )
164         {
165             ArtifactResolutionResult artifactResolutionResult = resolveArtifact( null, surefireArtifact );
166             for ( Artifact artifact : pluginArtifactMap.values() )
167             {
168                 if ( !artifactResolutionResult.getArtifacts().contains( artifact ) )
169                 {
170                     providerArtifacts.add( artifact );
171                 }
172             }
173         }
174         else
175         {
176             // Bit of a brute force strategy if not found. Should probably be improved
177             providerArtifacts.addAll( pluginArtifactMap.values() );
178         }
179         return providerArtifacts;
180     }
181 }