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.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.util.graph.manager.DependencyManagerUtils;
60 import org.eclipse.aether.util.graph.transformer.ConflictResolver;
61
62 import static org.apache.maven.internal.impl.Utils.cast;
63 import static org.apache.maven.internal.impl.Utils.map;
64 import static org.apache.maven.internal.impl.Utils.nonNull;
65
66 @Named
67 @Singleton
68 public class DefaultDependencyResolver implements DependencyResolver {
69
70 @Nonnull
71 @Override
72 public DependencyResolverResult collect(@Nonnull DependencyResolverRequest request)
73 throws DependencyResolverException, IllegalArgumentException {
74 nonNull(request, "request");
75 InternalSession session = InternalSession.from(request.getSession());
76
77 Artifact rootArtifact;
78 DependencyCoordinates root;
79 Collection<DependencyCoordinates> dependencies;
80 Collection<DependencyCoordinates> managedDependencies;
81 List<RemoteRepository> remoteRepositories;
82 if (request.getProject().isPresent()) {
83 Project project = request.getProject().get();
84 rootArtifact = project.getPomArtifact();
85 root = null;
86 dependencies = project.getDependencies();
87 managedDependencies = project.getManagedDependencies();
88 remoteRepositories = session.getService(ProjectManager.class).getRemoteProjectRepositories(project);
89 } else {
90 rootArtifact = request.getRootArtifact().orElse(null);
91 root = request.getRoot().orElse(null);
92 dependencies = request.getDependencies();
93 managedDependencies = request.getManagedDependencies();
94 remoteRepositories = session.getRemoteRepositories();
95 }
96 CollectRequest collectRequest = new CollectRequest()
97 .setRootArtifact(rootArtifact != null ? session.toArtifact(rootArtifact) : null)
98 .setRoot(root != null ? session.toDependency(root, false) : null)
99 .setDependencies(session.toDependencies(dependencies, false))
100 .setManagedDependencies(session.toDependencies(managedDependencies, true))
101 .setRepositories(session.toRepositories(remoteRepositories));
102
103 RepositorySystemSession systemSession = session.getSession();
104 if (request.getVerbose()) {
105 systemSession = new DefaultRepositorySystemSession(systemSession)
106 .setConfigProperty(ConflictResolver.CONFIG_PROP_VERBOSE, true)
107 .setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, true);
108 }
109
110 try {
111 final CollectResult result =
112 session.getRepositorySystem().collectDependencies(systemSession, collectRequest);
113 return new DefaultDependencyResolverResult(
114 null, result.getExceptions(), session.getNode(result.getRoot(), request.getVerbose()), 0);
115 } catch (DependencyCollectionException e) {
116 throw new DependencyResolverException("Unable to collect dependencies", e);
117 }
118 }
119
120 @Override
121 public List<Node> flatten(Session s, Node node, PathScope scope) throws DependencyResolverException {
122 InternalSession session = InternalSession.from(s);
123 DependencyNode root = cast(AbstractNode.class, node, "node").getDependencyNode();
124 List<DependencyNode> dependencies = session.getRepositorySystem()
125 .flattenDependencyNodes(session.getSession(), root, getScopeDependencyFilter(scope));
126 dependencies.remove(root);
127 return map(dependencies, session::getNode);
128 }
129
130 private static DependencyFilter getScopeDependencyFilter(PathScope scope) {
131 Set<String> scopes =
132 scope.dependencyScopes().stream().map(DependencyScope::id).collect(Collectors.toSet());
133 return (n, p) -> {
134 org.eclipse.aether.graph.Dependency d = n.getDependency();
135 return d == null || scopes.contains(d.getScope());
136 };
137 }
138
139
140
141
142
143
144
145 @Override
146 public DependencyResolverResult resolve(DependencyResolverRequest request)
147 throws DependencyResolverException, DependencyResolverException, ArtifactResolverException {
148 InternalSession session =
149 InternalSession.from(nonNull(request, "request").getSession());
150 DependencyResolverResult result;
151 DependencyResolverResult collectorResult = collect(request);
152 if (request.getRequestType() == DependencyResolverRequest.RequestType.COLLECT) {
153 result = collectorResult;
154 } else {
155 List<Node> nodes = flatten(session, collectorResult.getRoot(), request.getPathScope());
156 List<ArtifactCoordinates> coordinates = nodes.stream()
157 .map(Node::getDependency)
158 .filter(Objects::nonNull)
159 .map(Artifact::toCoordinates)
160 .collect(Collectors.toList());
161 Predicate<PathType> filter = request.getPathTypeFilter();
162 if (request.getRequestType() == DependencyResolverRequest.RequestType.FLATTEN) {
163 DefaultDependencyResolverResult flattenResult = new DefaultDependencyResolverResult(
164 null, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
165 for (Node node : nodes) {
166 flattenResult.addNode(node);
167 }
168 result = flattenResult;
169 } else {
170 PathModularizationCache cache = new PathModularizationCache();
171 DefaultDependencyResolverResult resolverResult = new DefaultDependencyResolverResult(
172 cache, collectorResult.getExceptions(), collectorResult.getRoot(), nodes.size());
173 ArtifactResolverResult artifactResolverResult =
174 session.getService(ArtifactResolver.class).resolve(session, coordinates);
175 for (Node node : nodes) {
176 Dependency d = node.getDependency();
177 Path path = (d != null) ? artifactResolverResult.getPath(d) : null;
178 try {
179 resolverResult.addDependency(node, d, filter, path);
180 } catch (IOException e) {
181 throw cannotReadModuleInfo(path, e);
182 }
183 }
184 result = resolverResult;
185 }
186 }
187 return result;
188 }
189
190 private static DependencyResolverException cannotReadModuleInfo(final Path path, final IOException cause) {
191 return new DependencyResolverException("Cannot read module information of " + path, cause);
192 }
193 }