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