1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.internal;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.util.LinkedHashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.apache.maven.RepositoryUtils;
30 import org.apache.maven.api.DependencyScope;
31 import org.apache.maven.model.Dependency;
32 import org.apache.maven.model.Plugin;
33 import org.apache.maven.plugin.PluginResolutionException;
34 import org.eclipse.aether.DefaultRepositorySystemSession;
35 import org.eclipse.aether.RepositorySystem;
36 import org.eclipse.aether.RepositorySystemSession;
37 import org.eclipse.aether.RequestTrace;
38 import org.eclipse.aether.artifact.Artifact;
39 import org.eclipse.aether.artifact.DefaultArtifact;
40 import org.eclipse.aether.collection.CollectRequest;
41 import org.eclipse.aether.collection.DependencyCollectionException;
42 import org.eclipse.aether.graph.DependencyFilter;
43 import org.eclipse.aether.graph.DependencyNode;
44 import org.eclipse.aether.repository.RemoteRepository;
45 import org.eclipse.aether.resolution.ArtifactDescriptorException;
46 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
47 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
48 import org.eclipse.aether.resolution.ArtifactRequest;
49 import org.eclipse.aether.resolution.ArtifactResolutionException;
50 import org.eclipse.aether.resolution.DependencyRequest;
51 import org.eclipse.aether.resolution.DependencyResolutionException;
52 import org.eclipse.aether.resolution.DependencyResult;
53 import org.eclipse.aether.util.filter.AndDependencyFilter;
54 import org.eclipse.aether.util.filter.ScopeDependencyFilter;
55 import org.eclipse.aether.util.graph.visitor.DependencyGraphDumper;
56 import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60
61
62
63
64
65
66
67 @Named
68 @Singleton
69 public class DefaultPluginDependenciesResolver implements PluginDependenciesResolver {
70 private static final String REPOSITORY_CONTEXT = "plugin";
71
72 private final Logger logger = LoggerFactory.getLogger(getClass());
73
74 private final RepositorySystem repoSystem;
75
76 private final List<MavenPluginDependenciesValidator> dependenciesValidators;
77
78 @Inject
79 public DefaultPluginDependenciesResolver(
80 RepositorySystem repoSystem, List<MavenPluginDependenciesValidator> dependenciesValidators) {
81 this.repoSystem = repoSystem;
82 this.dependenciesValidators = dependenciesValidators;
83 }
84
85 private Artifact toArtifact(Plugin plugin, RepositorySystemSession session) {
86 return new DefaultArtifact(
87 plugin.getGroupId(),
88 plugin.getArtifactId(),
89 null,
90 "jar",
91 plugin.getVersion(),
92 session.getArtifactTypeRegistry().get("maven-plugin"));
93 }
94
95 public Artifact resolve(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session)
96 throws PluginResolutionException {
97 RequestTrace trace = RequestTrace.newChild(null, plugin);
98
99 Artifact pluginArtifact = toArtifact(plugin, session);
100
101 try {
102 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession(session);
103 pluginSession.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(true, false));
104
105 ArtifactDescriptorRequest request =
106 new ArtifactDescriptorRequest(pluginArtifact, repositories, REPOSITORY_CONTEXT);
107 request.setTrace(trace);
108 ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor(pluginSession, request);
109
110 for (MavenPluginDependenciesValidator dependenciesValidator : dependenciesValidators) {
111 dependenciesValidator.validate(session, pluginArtifact, result);
112 }
113
114 pluginArtifact = result.getArtifact();
115
116 if (logger.isWarnEnabled() && !result.getRelocations().isEmpty()) {
117 String message = pluginArtifact instanceof org.apache.maven.repository.internal.RelocatedArtifact
118 ? ": " + ((org.apache.maven.repository.internal.RelocatedArtifact) pluginArtifact).getMessage()
119 : "";
120 logger.warn(
121 "The artifact {} has been relocated to {}{}",
122 result.getRelocations().get(0),
123 pluginArtifact,
124 message);
125 }
126
127 String requiredMavenVersion = (String) result.getProperties().get("prerequisites.maven");
128 if (requiredMavenVersion != null) {
129 Map<String, String> props = new LinkedHashMap<>(pluginArtifact.getProperties());
130 props.put("requiredMavenVersion", requiredMavenVersion);
131 pluginArtifact = pluginArtifact.setProperties(props);
132 }
133 } catch (ArtifactDescriptorException e) {
134 throw new PluginResolutionException(plugin, e);
135 }
136
137 try {
138 ArtifactRequest request = new ArtifactRequest(pluginArtifact, repositories, REPOSITORY_CONTEXT);
139 request.setTrace(trace);
140 pluginArtifact = repoSystem.resolveArtifact(session, request).getArtifact();
141 } catch (ArtifactResolutionException e) {
142 throw new PluginResolutionException(plugin, e);
143 }
144
145 return pluginArtifact;
146 }
147
148
149
150
151 public DependencyResult resolveCoreExtension(
152 Plugin plugin,
153 DependencyFilter dependencyFilter,
154 List<RemoteRepository> repositories,
155 RepositorySystemSession session)
156 throws PluginResolutionException {
157 return resolveInternal(plugin, null , dependencyFilter, repositories, session);
158 }
159
160 public DependencyResult resolvePlugin(
161 Plugin plugin,
162 Artifact pluginArtifact,
163 DependencyFilter dependencyFilter,
164 List<RemoteRepository> repositories,
165 RepositorySystemSession session)
166 throws PluginResolutionException {
167 return resolveInternal(plugin, pluginArtifact, dependencyFilter, repositories, session);
168 }
169
170 public DependencyNode resolve(
171 Plugin plugin,
172 Artifact pluginArtifact,
173 DependencyFilter dependencyFilter,
174 List<RemoteRepository> repositories,
175 RepositorySystemSession session)
176 throws PluginResolutionException {
177 return resolveInternal(plugin, pluginArtifact, dependencyFilter, repositories, session)
178 .getRoot();
179 }
180
181 private DependencyResult resolveInternal(
182 Plugin plugin,
183 Artifact pluginArtifact,
184 DependencyFilter dependencyFilter,
185 List<RemoteRepository> repositories,
186 RepositorySystemSession session)
187 throws PluginResolutionException {
188 RequestTrace trace = RequestTrace.newChild(null, plugin);
189
190 if (pluginArtifact == null) {
191 pluginArtifact = toArtifact(plugin, session);
192 }
193
194 DependencyFilter collectionFilter = new ScopeDependencyFilter("provided", "test");
195 DependencyFilter resolutionFilter = AndDependencyFilter.newInstance(collectionFilter, dependencyFilter);
196
197 DependencyNode node;
198
199 try {
200 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession(session);
201 pluginSession.setDependencySelector(session.getDependencySelector());
202 pluginSession.setDependencyGraphTransformer(session.getDependencyGraphTransformer());
203
204 CollectRequest request = new CollectRequest();
205 request.setRequestContext(REPOSITORY_CONTEXT);
206 request.setRepositories(repositories);
207 request.setRoot(new org.eclipse.aether.graph.Dependency(pluginArtifact, null));
208 for (Dependency dependency : plugin.getDependencies()) {
209 org.eclipse.aether.graph.Dependency pluginDep =
210 RepositoryUtils.toDependency(dependency, session.getArtifactTypeRegistry());
211 if (!DependencyScope.SYSTEM.is(pluginDep.getScope())) {
212 pluginDep = pluginDep.setScope(DependencyScope.RUNTIME.id());
213 }
214 request.addDependency(pluginDep);
215 }
216
217 DependencyRequest depRequest = new DependencyRequest(request, resolutionFilter);
218 depRequest.setTrace(trace);
219
220 request.setTrace(RequestTrace.newChild(trace, depRequest));
221
222 node = repoSystem.collectDependencies(pluginSession, request).getRoot();
223
224 if (logger.isDebugEnabled()) {
225 node.accept(new DependencyGraphDumper(logger::debug));
226 }
227
228 depRequest.setRoot(node);
229 return repoSystem.resolveDependencies(session, depRequest);
230 } catch (DependencyCollectionException e) {
231 throw new PluginResolutionException(plugin, e);
232 } catch (DependencyResolutionException e) {
233 throw new PluginResolutionException(plugin, e.getCause());
234 }
235 }
236 }