View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.dependency.resolvers;
20  
21  import java.util.Collection;
22  import java.util.HashSet;
23  import java.util.LinkedHashSet;
24  import java.util.Set;
25  import java.util.stream.Collectors;
26  
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.repository.ArtifactRepository;
29  import org.apache.maven.model.Dependency;
30  import org.apache.maven.plugin.MojoExecutionException;
31  import org.apache.maven.plugins.annotations.Mojo;
32  import org.apache.maven.plugins.dependency.utils.DependencyUtil;
33  import org.apache.maven.project.ProjectBuildingRequest;
34  import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
35  import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
36  import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
37  import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate;
38  import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
39  import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
40  
41  /**
42   * Goal that resolves all project dependencies, including plugins and reports and their dependencies.
43   *
44   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
45   * @author Maarten Mulders
46   * @since 2.0
47   */
48  @Mojo(name = "go-offline", threadSafe = true)
49  public class GoOfflineMojo extends AbstractResolveMojo {
50      /**
51       * Main entry into mojo. Gets the list of dependencies, resolves all that are not in the Reactor, and iterates
52       * through displaying the resolved versions.
53       *
54       * @throws MojoExecutionException with a message if an error occurs.
55       */
56      @Override
57      protected void doExecute() throws MojoExecutionException {
58  
59          try {
60              final Set<Artifact> plugins = resolvePluginArtifacts();
61  
62              final Set<Artifact> dependencies = resolveDependencyArtifacts();
63  
64              if (!isSilent()) {
65                  for (Artifact artifact : plugins) {
66                      this.getLog().info("Resolved plugin: " + DependencyUtil.getFormattedFileName(artifact, false));
67                  }
68  
69                  for (Artifact artifact : dependencies) {
70                      this.getLog().info("Resolved dependency: " + DependencyUtil.getFormattedFileName(artifact, false));
71                  }
72              }
73  
74          } catch (DependencyResolverException e) {
75              throw new MojoExecutionException(e.getMessage(), e);
76          }
77      }
78  
79      /**
80       * This method resolves the dependency artifacts from the project.
81       *
82       * @return set of resolved dependency artifacts.
83       * @throws DependencyResolverException in case of an error while resolving the artifacts.
84       */
85      protected Set<Artifact> resolveDependencyArtifacts() throws DependencyResolverException {
86          Collection<Dependency> dependencies = getProject().getDependencies();
87  
88          Set<DependableCoordinate> dependableCoordinates = dependencies.stream()
89                  .map(this::createDependendableCoordinateFromDependency)
90                  .collect(Collectors.toSet());
91  
92          ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest();
93  
94          return resolveDependableCoordinate(buildingRequest, dependableCoordinates, "dependencies");
95      }
96  
97      private Set<Artifact> resolveDependableCoordinate(
98              final ProjectBuildingRequest buildingRequest,
99              final Collection<DependableCoordinate> dependableCoordinates,
100             final String type)
101             throws DependencyResolverException {
102         final TransformableFilter filter = getTransformableFilter();
103 
104         this.getLog().debug("Resolving '" + type + "' with following repositories:");
105         for (ArtifactRepository repo : buildingRequest.getRemoteRepositories()) {
106             getLog().debug(repo.getId() + " (" + repo.getUrl() + ")");
107         }
108 
109         final Set<Artifact> results = new HashSet<>();
110 
111         for (DependableCoordinate dependableCoordinate : dependableCoordinates) {
112             final Iterable<ArtifactResult> artifactResults =
113                     getDependencyResolver().resolveDependencies(buildingRequest, dependableCoordinate, filter);
114 
115             for (final ArtifactResult artifactResult : artifactResults) {
116                 results.add(artifactResult.getArtifact());
117             }
118         }
119 
120         return results;
121     }
122 
123     private TransformableFilter getTransformableFilter() {
124         if (this.excludeReactor) {
125             return new ExcludeReactorProjectsDependencyFilter(this.reactorProjects, getLog());
126         } else {
127             return null;
128         }
129     }
130 
131     /**
132      * This method resolves the plugin artifacts from the project.
133      *
134      * @return set of resolved plugin artifacts.
135      * @throws DependencyResolverException in case of an error while resolving the artifacts.
136      */
137     protected Set<Artifact> resolvePluginArtifacts() throws DependencyResolverException {
138 
139         Set<Artifact> plugins = getProject().getPluginArtifacts();
140         Set<Artifact> reports = getProject().getReportArtifacts();
141 
142         Set<Artifact> artifacts = new LinkedHashSet<>();
143         artifacts.addAll(reports);
144         artifacts.addAll(plugins);
145 
146         Set<DependableCoordinate> dependableCoordinates = artifacts.stream()
147                 .map(this::createDependendableCoordinateFromArtifact)
148                 .collect(Collectors.toSet());
149 
150         ProjectBuildingRequest buildingRequest = newResolvePluginProjectBuildingRequest();
151 
152         return resolveDependableCoordinate(buildingRequest, dependableCoordinates, "plugins");
153     }
154 
155     private DependableCoordinate createDependendableCoordinateFromArtifact(final Artifact artifact) {
156         final DefaultDependableCoordinate result = new DefaultDependableCoordinate();
157         result.setGroupId(artifact.getGroupId());
158         result.setArtifactId(artifact.getArtifactId());
159         result.setVersion(artifact.getVersion());
160         result.setType(artifact.getType());
161         result.setClassifier(artifact.getClassifier());
162 
163         return result;
164     }
165 
166     private DependableCoordinate createDependendableCoordinateFromDependency(final Dependency dependency) {
167         final DefaultDependableCoordinate result = new DefaultDependableCoordinate();
168         result.setGroupId(dependency.getGroupId());
169         result.setArtifactId(dependency.getArtifactId());
170         result.setVersion(dependency.getVersion());
171         result.setType(dependency.getType());
172         result.setClassifier(dependency.getClassifier());
173 
174         return result;
175     }
176 
177     @Override
178     protected ArtifactsFilter getMarkedArtifactFilter() {
179         return null;
180     }
181 }