1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.impl;
20
21 import java.io.IOException;
22 import java.nio.file.Path;
23 import java.util.Collection;
24 import java.util.List;
25 import java.util.Objects;
26 import java.util.Set;
27 import java.util.function.Predicate;
28 import java.util.stream.Collectors;
29
30 import org.apache.maven.api.Artifact;
31 import org.apache.maven.api.ArtifactCoordinates;
32 import org.apache.maven.api.DependencyCoordinates;
33 import org.apache.maven.api.DependencyScope;
34 import org.apache.maven.api.Node;
35 import org.apache.maven.api.PathScope;
36 import org.apache.maven.api.PathType;
37 import org.apache.maven.api.Project;
38 import org.apache.maven.api.RemoteRepository;
39 import org.apache.maven.api.Session;
40 import org.apache.maven.api.annotations.Nonnull;
41 import org.apache.maven.api.annotations.Nullable;
42 import org.apache.maven.api.di.Named;
43 import org.apache.maven.api.di.Singleton;
44 import org.apache.maven.api.services.ArtifactResolver;
45 import org.apache.maven.api.services.ArtifactResolverException;
46 import org.apache.maven.api.services.ArtifactResolverResult;
47 import org.apache.maven.api.services.DependencyResolver;
48 import org.apache.maven.api.services.DependencyResolverException;
49 import org.apache.maven.api.services.DependencyResolverRequest;
50 import org.apache.maven.api.services.DependencyResolverResult;
51 import org.apache.maven.api.services.ProjectManager;
52 import org.eclipse.aether.DefaultRepositorySystemSession;
53 import org.eclipse.aether.RepositorySystemSession;
54 import org.eclipse.aether.collection.CollectRequest;
55 import org.eclipse.aether.collection.CollectResult;
56 import org.eclipse.aether.collection.DependencyCollectionException;
57 import org.eclipse.aether.graph.DependencyFilter;
58 import org.eclipse.aether.graph.DependencyNode;
59 import org.eclipse.aether.scope.ResolutionScope;
60 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
61 import org.eclipse.aether.util.graph.transformer.ConflictResolver;
62
63 import static org.apache.maven.impl.Utils.cast;
64 import static org.apache.maven.impl.Utils.map;
65 import static org.apache.maven.impl.Utils.nonNull;
66
67 @Named
68 @Singleton
69 public class DefaultDependencyResolver implements DependencyResolver {
70
71 @Nonnull
72 @Override
73 public DependencyResolverResult collect(@Nonnull DependencyResolverRequest request)
74 throws DependencyResolverException, IllegalArgumentException {
75 nonNull(request, "request");
76 InternalSession session = InternalSession.from(request.getSession());
77 RequestTraceHelper.ResolverTrace trace = RequestTraceHelper.enter(session, request);
78 try {
79 Artifact rootArtifact;
80 DependencyCoordinates root;
81 Collection<DependencyCoordinates> dependencies;
82 Collection<DependencyCoordinates> managedDependencies;
83 List<RemoteRepository> remoteRepositories;
84 if (request.getProject().isPresent()) {
85 Project project = request.getProject().get();
86 rootArtifact = project.getPomArtifact();
87 root = null;
88 dependencies = project.getDependencies();
89 managedDependencies = project.getManagedDependencies();
90 remoteRepositories = request.getRepositories() != null
91 ? request.getRepositories()
92 : session.getService(ProjectManager.class).getRemoteProjectRepositories(project);
93 } else {
94 rootArtifact = request.getRootArtifact().orElse(null);
95 root = request.getRoot().orElse(null);
96 dependencies = request.getDependencies();
97 managedDependencies = request.getManagedDependencies();
98 remoteRepositories =
99 request.getRepositories() != null ? request.getRepositories() : session.getRemoteRepositories();
100 }
101 ResolutionScope resolutionScope = null;
102 if (request.getPathScope() != null) {
103 resolutionScope = session.getSession()
104 .getScopeManager()
105 .getResolutionScope(request.getPathScope().id())
106 .orElseThrow();
107 }
108 CollectRequest collectRequest = new CollectRequest()
109 .setRootArtifact(rootArtifact != null ? session.toArtifact(rootArtifact) : null)
110 .setRoot(root != null ? session.toDependency(root, false) : null)
111 .setDependencies(session.toDependencies(dependencies, false))
112 .setManagedDependencies(session.toDependencies(managedDependencies, true))
113 .setRepositories(session.toRepositories(remoteRepositories))
114 .setRequestContext(trace.context())
115 .setTrace(trace.trace());
116 collectRequest.setResolutionScope(resolutionScope);
117
118 RepositorySystemSession systemSession = session.getSession();
119 if (request.getVerbose()) {
120 systemSession = new DefaultRepositorySystemSession(systemSession)
121 .setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true)
122 .setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
123 }
124
125 try {
126 final CollectResult result =
127 session.getRepositorySystem().collectDependencies(systemSession, collectRequest);
128 return new DefaultDependencyResolverResult(
129 null, null, result.getExceptions(), session.getNode(result.getRoot(), request.getVerbose()), 0);
130 } catch (DependencyCollectionException e) {
131 throw new DependencyResolverException("Unable to collect dependencies", e);
132 }
133 } finally {
134 RequestTraceHelper.exit(trace);
135 }
136 }
137
138 @Nonnull
139 @Override
140 public List<Node> flatten(@Nonnull Session s, @Nonnull Node node, @Nullable PathScope scope)
141 throws DependencyResolverException {
142 InternalSession session = InternalSession.from(s);
143 DependencyNode root = cast(AbstractNode.class, node, "node").getDependencyNode();
144 List<DependencyNode> dependencies = session.getRepositorySystem()
145 .flattenDependencyNodes(session.getSession(), root, getScopeDependencyFilter(scope));
146 dependencies.remove(root);
147 return map(dependencies, session::getNode);
148 }
149
150 private static DependencyFilter getScopeDependencyFilter(PathScope scope) {
151 if (scope == null) {
152 return null;
153 }
154 Set<String> scopes =
155 scope.dependencyScopes().stream().map(DependencyScope::id).collect(Collectors.toSet());
156 return (n, p) -> {
157 org.eclipse.aether.graph.Dependency d = n.getDependency();
158 return d == null || scopes.contains(d.getScope());
159 };
160 }
161
162
163
164
165
166
167
168 @Override
169 public DependencyResolverResult resolve(DependencyResolverRequest request)
170 throws DependencyResolverException, ArtifactResolverException {
171 InternalSession session =
172 InternalSession.from(nonNull(request, "request").getSession());
173 RequestTraceHelper.ResolverTrace trace = RequestTraceHelper.enter(session, request);
174 try {
175 DependencyResolverResult result;
176 DependencyResolverResult collectorResult = collect(request);
177 List<RemoteRepository> repositories = request.getRepositories() != null
178 ? request.getRepositories()
179 : request.getProject().isPresent()
180 ? session.getService(ProjectManager.class)
181 .getRemoteProjectRepositories(
182 request.getProject().get())
183 : session.getRemoteRepositories();
184 if (request.getRequestType() == DependencyResolverRequest.RequestType.COLLECT) {
185 result = collectorResult;
186 } else {
187 List<Node> nodes = flatten(session, collectorResult.getRoot(), request.getPathScope());
188 List<ArtifactCoordinates> coordinates = nodes.stream()
189 .map(Node::getDependency)
190 .filter(Objects::nonNull)
191 .map(Artifact::toCoordinates)
192 .collect(Collectors.toList());
193 Predicate<PathType> filter = request.getPathTypeFilter();
194 if (request.getRequestType() == DependencyResolverRequest.RequestType.FLATTEN) {
195 DefaultDependencyResolverResult flattenResult = new DefaultDependencyResolverResult(
196 null, null, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
197 for (Node node : nodes) {
198 flattenResult.addNode(node);
199 }
200 result = flattenResult;
201 } else {
202 PathModularizationCache cache =
203 new PathModularizationCache();
204 DefaultDependencyResolverResult resolverResult = new DefaultDependencyResolverResult(
205 null, cache, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
206 ArtifactResolverResult artifactResolverResult =
207 session.getService(ArtifactResolver.class).resolve(session, coordinates, repositories);
208 for (Node node : nodes) {
209 Path path = (node.getArtifact() != null)
210 ? artifactResolverResult
211 .getResult(node.getArtifact().toCoordinates())
212 .getPath()
213 : null;
214 try {
215 resolverResult.addDependency(node, node.getDependency(), filter, path);
216 } catch (IOException e) {
217 throw cannotReadModuleInfo(path, e);
218 }
219 }
220 result = resolverResult;
221 }
222 }
223 return result;
224 } finally {
225 RequestTraceHelper.exit(trace);
226 }
227 }
228
229 private static DependencyResolverException cannotReadModuleInfo(final Path path, final IOException cause) {
230 return new DependencyResolverException("Cannot read module information of " + path, cause);
231 }
232 }