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 java.util.Collection;
22 import java.util.LinkedHashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Objects;
26
27 import org.apache.maven.RepositoryUtils;
28 import org.apache.maven.model.Dependency;
29 import org.apache.maven.model.Plugin;
30 import org.apache.maven.plugin.PluginResolutionException;
31 import org.codehaus.plexus.component.annotations.Component;
32 import org.codehaus.plexus.component.annotations.Requirement;
33 import org.codehaus.plexus.logging.Logger;
34 import org.codehaus.plexus.util.StringUtils;
35 import org.eclipse.aether.DefaultRepositorySystemSession;
36 import org.eclipse.aether.RepositorySystem;
37 import org.eclipse.aether.RepositorySystemSession;
38 import org.eclipse.aether.RequestTrace;
39 import org.eclipse.aether.artifact.Artifact;
40 import org.eclipse.aether.artifact.DefaultArtifact;
41 import org.eclipse.aether.collection.CollectRequest;
42 import org.eclipse.aether.collection.DependencyCollectionException;
43 import org.eclipse.aether.collection.DependencySelector;
44 import org.eclipse.aether.graph.DependencyFilter;
45 import org.eclipse.aether.graph.DependencyNode;
46 import org.eclipse.aether.graph.DependencyVisitor;
47 import org.eclipse.aether.repository.RemoteRepository;
48 import org.eclipse.aether.resolution.ArtifactDescriptorException;
49 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
50 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
51 import org.eclipse.aether.resolution.ArtifactRequest;
52 import org.eclipse.aether.resolution.ArtifactResolutionException;
53 import org.eclipse.aether.resolution.DependencyRequest;
54 import org.eclipse.aether.resolution.DependencyResolutionException;
55 import org.eclipse.aether.util.artifact.JavaScopes;
56 import org.eclipse.aether.util.filter.AndDependencyFilter;
57 import org.eclipse.aether.util.filter.ScopeDependencyFilter;
58 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
59 import org.eclipse.aether.util.graph.selector.AndDependencySelector;
60 import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
61
62
63
64
65
66
67
68
69
70 @Component(role = PluginDependenciesResolver.class)
71 public class DefaultPluginDependenciesResolver implements PluginDependenciesResolver {
72
73 private static final String REPOSITORY_CONTEXT = "plugin";
74
75 @Requirement
76 private Logger logger;
77
78 @Requirement
79 private RepositorySystem repoSystem;
80
81 private Artifact toArtifact(Plugin plugin, RepositorySystemSession session) {
82 return new DefaultArtifact(
83 plugin.getGroupId(),
84 plugin.getArtifactId(),
85 null,
86 "jar",
87 plugin.getVersion(),
88 session.getArtifactTypeRegistry().get("maven-plugin"));
89 }
90
91 public Artifact resolve(Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session)
92 throws PluginResolutionException {
93 RequestTrace trace = RequestTrace.newChild(null, plugin);
94
95 Artifact pluginArtifact = toArtifact(plugin, session);
96
97 try {
98 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession(session);
99 pluginSession.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(true, false));
100
101 ArtifactDescriptorRequest request =
102 new ArtifactDescriptorRequest(pluginArtifact, repositories, REPOSITORY_CONTEXT);
103 request.setTrace(trace);
104 ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor(pluginSession, request);
105
106 pluginArtifact = result.getArtifact();
107
108 if (logger.isWarnEnabled()) {
109 if (!result.getRelocations().isEmpty()) {
110 String message = pluginArtifact instanceof org.apache.maven.repository.internal.RelocatedArtifact
111 ? ((org.apache.maven.repository.internal.RelocatedArtifact) pluginArtifact).getMessage()
112 : null;
113 logger.warn("The artifact " + result.getRelocations().get(0) + " has been relocated to "
114 + pluginArtifact + (message != null ? ": " + message : ""));
115 }
116 }
117
118 String requiredMavenVersion = (String) result.getProperties().get("prerequisites.maven");
119 if (requiredMavenVersion != null) {
120 Map<String, String> props = new LinkedHashMap<>(pluginArtifact.getProperties());
121 props.put("requiredMavenVersion", requiredMavenVersion);
122 pluginArtifact = pluginArtifact.setProperties(props);
123 }
124 } catch (ArtifactDescriptorException e) {
125 throw new PluginResolutionException(plugin, e);
126 }
127
128 try {
129 ArtifactRequest request = new ArtifactRequest(pluginArtifact, repositories, REPOSITORY_CONTEXT);
130 request.setTrace(trace);
131 pluginArtifact = repoSystem.resolveArtifact(session, request).getArtifact();
132 } catch (ArtifactResolutionException e) {
133 throw new PluginResolutionException(plugin, e);
134 }
135
136 return pluginArtifact;
137 }
138
139
140
141
142 public DependencyNode resolveCoreExtension(
143 Plugin plugin,
144 DependencyFilter dependencyFilter,
145 List<RemoteRepository> repositories,
146 RepositorySystemSession session)
147 throws PluginResolutionException {
148 return resolveInternal(plugin, null , dependencyFilter, repositories, session);
149 }
150
151 public DependencyNode resolve(
152 Plugin plugin,
153 Artifact pluginArtifact,
154 DependencyFilter dependencyFilter,
155 List<RemoteRepository> repositories,
156 RepositorySystemSession session)
157 throws PluginResolutionException {
158 return resolveInternal(plugin, pluginArtifact, dependencyFilter, repositories, session);
159 }
160
161 private DependencyNode resolveInternal(
162 Plugin plugin,
163 Artifact pluginArtifact,
164 DependencyFilter dependencyFilter,
165 List<RemoteRepository> repositories,
166 RepositorySystemSession session)
167 throws PluginResolutionException {
168 RequestTrace trace = RequestTrace.newChild(null, plugin);
169
170 if (pluginArtifact == null) {
171 pluginArtifact = toArtifact(plugin, session);
172 }
173
174 DependencyFilter collectionFilter = new ScopeDependencyFilter("provided", "test");
175 DependencyFilter resolutionFilter = AndDependencyFilter.newInstance(collectionFilter, dependencyFilter);
176
177 DependencyNode node;
178
179 try {
180 DependencySelector selector =
181 AndDependencySelector.newInstance(session.getDependencySelector(), new WagonExcluder());
182
183 DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession(session);
184 pluginSession.setDependencySelector(selector);
185 pluginSession.setDependencyGraphTransformer(session.getDependencyGraphTransformer());
186
187 CollectRequest request = new CollectRequest();
188 request.setRequestContext(REPOSITORY_CONTEXT);
189 request.setRepositories(repositories);
190 request.setRoot(new org.eclipse.aether.graph.Dependency(pluginArtifact, null));
191 for (Dependency dependency : plugin.getDependencies()) {
192 org.eclipse.aether.graph.Dependency pluginDep =
193 RepositoryUtils.toDependency(dependency, session.getArtifactTypeRegistry());
194 if (!JavaScopes.SYSTEM.equals(pluginDep.getScope())) {
195 pluginDep = pluginDep.setScope(JavaScopes.RUNTIME);
196 }
197 request.addDependency(pluginDep);
198 }
199
200 DependencyRequest depRequest = new DependencyRequest(request, resolutionFilter);
201 depRequest.setTrace(trace);
202
203 request.setTrace(RequestTrace.newChild(trace, depRequest));
204
205 node = repoSystem.collectDependencies(pluginSession, request).getRoot();
206
207 if (logger.isDebugEnabled()) {
208 node.accept(new GraphLogger());
209 }
210
211 depRequest.setRoot(node);
212 repoSystem.resolveDependencies(session, depRequest);
213 } catch (DependencyCollectionException e) {
214 throw new PluginResolutionException(plugin, e);
215 } catch (DependencyResolutionException e) {
216 throw new PluginResolutionException(plugin, e.getCause());
217 }
218
219 return node;
220 }
221
222
223 class GraphLogger implements DependencyVisitor {
224
225 private String indent = "";
226
227 public boolean visitEnter(DependencyNode node) {
228 StringBuilder buffer = new StringBuilder(128);
229 buffer.append(indent);
230 org.eclipse.aether.graph.Dependency dep = node.getDependency();
231 if (dep != null) {
232 org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
233
234 buffer.append(art);
235 if (StringUtils.isNotEmpty(dep.getScope())) {
236 buffer.append(':').append(dep.getScope());
237 }
238
239 if (dep.isOptional()) {
240 buffer.append(" (optional)");
241 }
242
243
244
245
246 if ((node.getManagedBits() & DependencyNode.MANAGED_SCOPE) == DependencyNode.MANAGED_SCOPE) {
247 final String premanagedScope = DependencyManagerUtils.getPremanagedScope(node);
248 buffer.append(" (scope managed from ");
249 buffer.append(Objects.toString(premanagedScope, "default"));
250 buffer.append(')');
251 }
252
253 if ((node.getManagedBits() & DependencyNode.MANAGED_VERSION) == DependencyNode.MANAGED_VERSION) {
254 final String premanagedVersion = DependencyManagerUtils.getPremanagedVersion(node);
255 buffer.append(" (version managed from ");
256 buffer.append(Objects.toString(premanagedVersion, "default"));
257 buffer.append(')');
258 }
259
260 if ((node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL) == DependencyNode.MANAGED_OPTIONAL) {
261 final Boolean premanagedOptional = DependencyManagerUtils.getPremanagedOptional(node);
262 buffer.append(" (optionality managed from ");
263 buffer.append(Objects.toString(premanagedOptional, "default"));
264 buffer.append(')');
265 }
266
267 if ((node.getManagedBits() & DependencyNode.MANAGED_EXCLUSIONS) == DependencyNode.MANAGED_EXCLUSIONS) {
268 final Collection<org.eclipse.aether.graph.Exclusion> premanagedExclusions =
269 DependencyManagerUtils.getPremanagedExclusions(node);
270
271 buffer.append(" (exclusions managed from ");
272 buffer.append(Objects.toString(premanagedExclusions, "default"));
273 buffer.append(')');
274 }
275
276 if ((node.getManagedBits() & DependencyNode.MANAGED_PROPERTIES) == DependencyNode.MANAGED_PROPERTIES) {
277 final Map<String, String> premanagedProperties =
278 DependencyManagerUtils.getPremanagedProperties(node);
279
280 buffer.append(" (properties managed from ");
281 buffer.append(Objects.toString(premanagedProperties, "default"));
282 buffer.append(')');
283 }
284 }
285
286 logger.debug(buffer.toString());
287 indent += " ";
288 return true;
289 }
290
291 public boolean visitLeave(DependencyNode node) {
292 indent = indent.substring(0, indent.length() - 3);
293 return true;
294 }
295 }
296 }