1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.internal.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.Dependency;
33 import org.apache.maven.api.DependencyCoordinates;
34 import org.apache.maven.api.DependencyScope;
35 import org.apache.maven.api.Node;
36 import org.apache.maven.api.PathScope;
37 import org.apache.maven.api.PathType;
38 import org.apache.maven.api.Project;
39 import org.apache.maven.api.RemoteRepository;
40 import org.apache.maven.api.Session;
41 import org.apache.maven.api.annotations.Nonnull;
42 import org.apache.maven.api.annotations.Nullable;
43 import org.apache.maven.api.di.Named;
44 import org.apache.maven.api.di.Singleton;
45 import org.apache.maven.api.services.ArtifactResolver;
46 import org.apache.maven.api.services.ArtifactResolverException;
47 import org.apache.maven.api.services.ArtifactResolverResult;
48 import org.apache.maven.api.services.DependencyResolver;
49 import org.apache.maven.api.services.DependencyResolverException;
50 import org.apache.maven.api.services.DependencyResolverRequest;
51 import org.apache.maven.api.services.DependencyResolverResult;
52 import org.apache.maven.api.services.ProjectManager;
53 import org.eclipse.aether.DefaultRepositorySystemSession;
54 import org.eclipse.aether.RepositorySystemSession;
55 import org.eclipse.aether.collection.CollectRequest;
56 import org.eclipse.aether.collection.CollectResult;
57 import org.eclipse.aether.collection.DependencyCollectionException;
58 import org.eclipse.aether.graph.DependencyFilter;
59 import org.eclipse.aether.graph.DependencyNode;
60 import org.eclipse.aether.scope.ResolutionScope;
61 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
62 import org.eclipse.aether.util.graph.transformer.ConflictResolver;
63
64 import static org.apache.maven.internal.impl.Utils.cast;
65 import static org.apache.maven.internal.impl.Utils.map;
66 import static org.apache.maven.internal.impl.Utils.nonNull;
67
68 @Named
69 @Singleton
70 public class DefaultDependencyResolver implements DependencyResolver {
71
72 @Nonnull
73 @Override
74 public DependencyResolverResult collect(@Nonnull DependencyResolverRequest request)
75 throws DependencyResolverException, IllegalArgumentException {
76 nonNull(request, "request");
77 InternalSession session = InternalSession.from(request.getSession());
78
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 collectRequest.setResolutionScope(resolutionScope);
115
116 RepositorySystemSession systemSession = session.getSession();
117 if (request.getVerbose()) {
118 systemSession = new DefaultRepositorySystemSession(systemSession)
119 .setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true)
120 .setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
121 }
122
123 try {
124 final CollectResult result =
125 session.getRepositorySystem().collectDependencies(systemSession, collectRequest);
126 return new DefaultDependencyResolverResult(
127 null, result.getExceptions(), session.getNode(result.getRoot(), request.getVerbose()), 0);
128 } catch (DependencyCollectionException e) {
129 throw new DependencyResolverException("Unable to collect dependencies", e);
130 }
131 }
132
133 @Nonnull
134 @Override
135 public List<Node> flatten(@Nonnull Session s, @Nonnull Node node, @Nullable PathScope scope)
136 throws DependencyResolverException {
137 InternalSession session = InternalSession.from(s);
138 DependencyNode root = cast(AbstractNode.class, node, "node").getDependencyNode();
139 List<DependencyNode> dependencies = session.getRepositorySystem()
140 .flattenDependencyNodes(session.getSession(), root, getScopeDependencyFilter(scope));
141 dependencies.remove(root);
142 return map(dependencies, session::getNode);
143 }
144
145 private static DependencyFilter getScopeDependencyFilter(PathScope scope) {
146 if (scope == null) {
147 return null;
148 }
149 Set<String> scopes =
150 scope.dependencyScopes().stream().map(DependencyScope::id).collect(Collectors.toSet());
151 return (n, p) -> {
152 org.eclipse.aether.graph.Dependency d = n.getDependency();
153 return d == null || scopes.contains(d.getScope());
154 };
155 }
156
157
158
159
160
161
162
163 @Override
164 public DependencyResolverResult resolve(DependencyResolverRequest request)
165 throws DependencyResolverException, DependencyResolverException, ArtifactResolverException {
166 InternalSession session =
167 InternalSession.from(nonNull(request, "request").getSession());
168 DependencyResolverResult result;
169 DependencyResolverResult collectorResult = collect(request);
170 List<RemoteRepository> repositories =
171 request.getRepositories() != null ? request.getRepositories() : session.getRemoteRepositories();
172 if (request.getRequestType() == DependencyResolverRequest.RequestType.COLLECT) {
173 result = collectorResult;
174 } else {
175 List<Node> nodes = flatten(session, collectorResult.getRoot(), request.getPathScope());
176 List<ArtifactCoordinates> coordinates = nodes.stream()
177 .map(Node::getDependency)
178 .filter(Objects::nonNull)
179 .map(Artifact::toCoordinates)
180 .collect(Collectors.toList());
181 Predicate<PathType> filter = request.getPathTypeFilter();
182 if (request.getRequestType() == DependencyResolverRequest.RequestType.FLATTEN) {
183 DefaultDependencyResolverResult flattenResult = new DefaultDependencyResolverResult(
184 null, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
185 for (Node node : nodes) {
186 flattenResult.addNode(node);
187 }
188 result = flattenResult;
189 } else {
190 PathModularizationCache cache = new PathModularizationCache();
191 DefaultDependencyResolverResult resolverResult = new DefaultDependencyResolverResult(
192 cache, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
193 ArtifactResolverResult artifactResolverResult =
194 session.getService(ArtifactResolver.class).resolve(session, coordinates, repositories);
195 for (Node node : nodes) {
196 Dependency d = node.getDependency();
197 Path path = (d != null) ? artifactResolverResult.getPath(d) : null;
198 try {
199 resolverResult.addDependency(node, d, filter, path);
200 } catch (IOException e) {
201 throw cannotReadModuleInfo(path, e);
202 }
203 }
204 result = resolverResult;
205 }
206 }
207 return result;
208 }
209
210 private static DependencyResolverException cannotReadModuleInfo(final Path path, final IOException cause) {
211 return new DependencyResolverException("Cannot read module information of " + path, cause);
212 }
213 }