1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.dependency.resolvers;
20
21 import javax.inject.Inject;
22
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Set;
29 import java.util.function.Predicate;
30 import java.util.stream.Collectors;
31
32 import org.apache.maven.RepositoryUtils;
33 import org.apache.maven.artifact.Artifact;
34 import org.apache.maven.artifact.DefaultArtifact;
35 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
36 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
37 import org.apache.maven.execution.MavenSession;
38 import org.apache.maven.model.Dependency;
39 import org.apache.maven.model.DependencyManagement;
40 import org.apache.maven.model.Plugin;
41 import org.apache.maven.plugin.MojoExecutionException;
42 import org.apache.maven.plugins.annotations.Mojo;
43 import org.apache.maven.plugins.annotations.Parameter;
44 import org.apache.maven.plugins.dependency.fromDependencies.AbstractDependencyFilterMojo;
45 import org.apache.maven.plugins.dependency.utils.DependencyUtil;
46 import org.apache.maven.plugins.dependency.utils.ResolverUtil;
47 import org.apache.maven.project.MavenProject;
48 import org.apache.maven.project.ProjectBuilder;
49 import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
50 import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter;
51 import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter;
52 import org.apache.maven.shared.artifact.filter.collection.ClassifierFilter;
53 import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts;
54 import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter;
55 import org.apache.maven.shared.artifact.filter.collection.ScopeFilter;
56 import org.apache.maven.shared.artifact.filter.collection.TypeFilter;
57 import org.eclipse.aether.artifact.ArtifactTypeRegistry;
58 import org.eclipse.aether.resolution.ArtifactResolutionException;
59 import org.eclipse.aether.resolution.DependencyResolutionException;
60 import org.sonatype.plexus.build.incremental.BuildContext;
61
62 import static java.util.Optional.ofNullable;
63
64
65
66
67
68
69
70
71
72 @Mojo(name = "go-offline", threadSafe = true)
73 public class GoOfflineMojo extends AbstractDependencyFilterMojo {
74
75
76
77
78
79
80 @Parameter(property = "excludeReactor", defaultValue = "true")
81 protected boolean excludeReactor;
82
83 @Inject
84 public GoOfflineMojo(
85 MavenSession session,
86 BuildContext buildContext,
87 MavenProject project,
88 ResolverUtil resolverUtil,
89 ProjectBuilder projectBuilder,
90 ArtifactHandlerManager artifactHandlerManager) {
91 super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager);
92 }
93
94
95
96
97
98
99
100 @Override
101 protected void doExecute() throws MojoExecutionException {
102
103 try {
104 final Set<Plugin> plugins = getProjectPlugins();
105
106 for (Plugin plugin : plugins) {
107 org.eclipse.aether.artifact.Artifact artifact =
108 getResolverUtil().resolvePlugin(plugin);
109
110 logMessage("Resolved plugin: "
111 + DependencyUtil.getFormattedFileName(RepositoryUtils.toArtifact(artifact), false));
112 if (!excludeTransitive) {
113 logMessage("Resolved plugin dependency:");
114 List<org.eclipse.aether.artifact.Artifact> artifacts =
115 getResolverUtil().resolveDependencies(plugin, getDependencyFilter());
116 for (org.eclipse.aether.artifact.Artifact a : artifacts) {
117 logMessage(
118 " " + DependencyUtil.getFormattedFileName(RepositoryUtils.toArtifact(a), false));
119 }
120 }
121 }
122
123 final List<org.eclipse.aether.artifact.Artifact> dependencies = resolveDependencyArtifacts();
124
125 for (org.eclipse.aether.artifact.Artifact artifact : dependencies) {
126 logMessage("Resolved dependency: "
127 + DependencyUtil.getFormattedFileName(RepositoryUtils.toArtifact(artifact), false));
128 }
129
130 } catch (ArtifactFilterException | ArtifactResolutionException | DependencyResolutionException e) {
131 throw new MojoExecutionException(e.getMessage(), e);
132 }
133 }
134
135 private Predicate<Dependency> getDependencyFilter() {
136 if (excludeReactor) {
137 return new ExcludeReactorProjectsDependencyFilter(session.getProjects());
138 } else {
139 return __ -> true;
140 }
141 }
142
143 private void logMessage(String message) {
144 if (isSilent()) {
145 getLog().debug(message);
146 } else {
147 getLog().info(message);
148 }
149 }
150
151
152
153
154
155
156
157
158 protected List<org.eclipse.aether.artifact.Artifact> resolveDependencyArtifacts()
159 throws ArtifactFilterException, DependencyResolutionException {
160 Collection<Dependency> dependencies = getProject().getDependencies();
161
162 dependencies = filterDependencies(dependencies);
163
164 Predicate<Dependency> excludeReactorProjectsDependencyFilter = d -> true;
165 if (this.excludeReactor) {
166 excludeReactorProjectsDependencyFilter = new ExcludeReactorProjectsDependencyFilter(session.getProjects());
167 }
168
169 ArtifactTypeRegistry artifactTypeRegistry =
170 session.getRepositorySession().getArtifactTypeRegistry();
171
172 List<org.eclipse.aether.graph.Dependency> dependableCoordinates = dependencies.stream()
173 .filter(excludeReactorProjectsDependencyFilter)
174 .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry))
175 .collect(Collectors.toList());
176
177 List<org.eclipse.aether.graph.Dependency> managedDependencies = ofNullable(
178 getProject().getDependencyManagement())
179 .map(DependencyManagement::getDependencies)
180 .map(list -> list.stream()
181 .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry))
182 .collect(Collectors.toList()))
183 .orElse(null);
184
185 return getResolverUtil()
186 .resolveDependenciesForArtifact(
187 RepositoryUtils.toArtifact(getProject().getArtifact()),
188 dependableCoordinates,
189 managedDependencies,
190 getProject().getRemoteProjectRepositories());
191 }
192
193
194
195
196
197
198 private Set<Plugin> getProjectPlugins() {
199 Predicate<Plugin> pluginsFilter = new PluginsIncludeExcludeFilter(
200 toList(includeGroupIds),
201 toList(excludeGroupIds),
202 toList(includeArtifactIds),
203 toList(excludeArtifactIds));
204
205 Predicate<Plugin> reactorExclusionFilter = plugin -> true;
206 if (excludeReactor) {
207 reactorExclusionFilter = new PluginsReactorExcludeFilter(session.getProjects());
208 }
209
210 return getResolverUtil().getProjectPlugins(getProject()).stream()
211 .filter(reactorExclusionFilter)
212 .filter(pluginsFilter)
213 .collect(Collectors.toSet());
214 }
215
216 private List<String> toList(String list) {
217 if (list == null || list.isEmpty()) {
218 return Collections.emptyList();
219 }
220 return Arrays.asList(DependencyUtil.cleanToBeTokenizedString(list).split(","));
221 }
222
223 private Collection<Dependency> filterDependencies(Collection<Dependency> deps) throws ArtifactFilterException {
224
225 Set<Artifact> artifacts = createArtifactSetFromDependencies(deps);
226
227 final FilterArtifacts filter = getArtifactsFilter();
228 artifacts = filter.filter(artifacts);
229
230 return createDependencySetFromArtifacts(artifacts);
231 }
232
233 private Set<Artifact> createArtifactSetFromDependencies(Collection<Dependency> deps) {
234 Set<Artifact> artifacts = new HashSet<>();
235 for (Dependency dep : deps) {
236 DefaultArtifactHandler handler = new DefaultArtifactHandler(dep.getType());
237 artifacts.add(new DefaultArtifact(
238 dep.getGroupId(),
239 dep.getArtifactId(),
240 dep.getVersion(),
241 dep.getScope(),
242 dep.getType(),
243 dep.getClassifier(),
244 handler));
245 }
246 return artifacts;
247 }
248
249 private Collection<Dependency> createDependencySetFromArtifacts(Set<Artifact> artifacts) {
250 Set<Dependency> dependencies = new HashSet<>();
251
252 for (Artifact artifact : artifacts) {
253 Dependency d = new Dependency();
254 d.setGroupId(artifact.getGroupId());
255 d.setArtifactId(artifact.getArtifactId());
256 d.setVersion(artifact.getVersion());
257 d.setType(artifact.getType());
258 d.setClassifier(artifact.getClassifier());
259 d.setScope(artifact.getScope());
260 dependencies.add(d);
261 }
262
263 return dependencies;
264 }
265
266
267
268
269
270 protected FilterArtifacts getArtifactsFilter() {
271 final FilterArtifacts filter = new FilterArtifacts();
272
273 if (excludeReactor) {
274 filter.addFilter(new ExcludeReactorProjectsArtifactFilter(session.getProjects(), getLog()));
275 }
276
277 filter.addFilter(new ScopeFilter(
278 DependencyUtil.cleanToBeTokenizedString(this.includeScope),
279 DependencyUtil.cleanToBeTokenizedString(this.excludeScope)));
280
281 filter.addFilter(new TypeFilter(
282 DependencyUtil.cleanToBeTokenizedString(this.includeTypes),
283 DependencyUtil.cleanToBeTokenizedString(this.excludeTypes)));
284
285 filter.addFilter(new ClassifierFilter(
286 DependencyUtil.cleanToBeTokenizedString(this.includeClassifiers),
287 DependencyUtil.cleanToBeTokenizedString(this.excludeClassifiers)));
288
289 filter.addFilter(new GroupIdFilter(
290 DependencyUtil.cleanToBeTokenizedString(this.includeGroupIds),
291 DependencyUtil.cleanToBeTokenizedString(this.excludeGroupIds)));
292
293 filter.addFilter(new ArtifactIdFilter(
294 DependencyUtil.cleanToBeTokenizedString(this.includeArtifactIds),
295 DependencyUtil.cleanToBeTokenizedString(this.excludeArtifactIds)));
296
297 return filter;
298 }
299
300 @Override
301 protected ArtifactsFilter getMarkedArtifactFilter() {
302 return null;
303 }
304 }