1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl.collect.df;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.util.Collections;
26 import java.util.List;
27
28 import org.eclipse.aether.RepositorySystemSession;
29 import org.eclipse.aether.RequestTrace;
30 import org.eclipse.aether.artifact.Artifact;
31 import org.eclipse.aether.collection.CollectRequest;
32 import org.eclipse.aether.collection.DependencyManager;
33 import org.eclipse.aether.collection.DependencySelector;
34 import org.eclipse.aether.collection.DependencyTraverser;
35 import org.eclipse.aether.collection.VersionFilter;
36 import org.eclipse.aether.graph.DefaultDependencyNode;
37 import org.eclipse.aether.graph.Dependency;
38 import org.eclipse.aether.graph.DependencyNode;
39 import org.eclipse.aether.impl.ArtifactDescriptorReader;
40 import org.eclipse.aether.impl.RemoteRepositoryManager;
41 import org.eclipse.aether.impl.VersionRangeResolver;
42 import org.eclipse.aether.internal.impl.collect.DataPool;
43 import org.eclipse.aether.internal.impl.collect.DefaultDependencyCollectionContext;
44 import org.eclipse.aether.internal.impl.collect.DefaultDependencyCycle;
45 import org.eclipse.aether.internal.impl.collect.DefaultVersionFilterContext;
46 import org.eclipse.aether.internal.impl.collect.DependencyCollectorDelegate;
47 import org.eclipse.aether.internal.impl.collect.PremanagedDependency;
48 import org.eclipse.aether.repository.RemoteRepository;
49 import org.eclipse.aether.resolution.ArtifactDescriptorException;
50 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
51 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
52 import org.eclipse.aether.resolution.VersionRangeRequest;
53 import org.eclipse.aether.resolution.VersionRangeResolutionException;
54 import org.eclipse.aether.resolution.VersionRangeResult;
55 import org.eclipse.aether.util.ConfigUtils;
56 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
57 import org.eclipse.aether.version.Version;
58
59
60
61
62
63
64
65 @Singleton
66 @Named(DfDependencyCollector.NAME)
67 public class DfDependencyCollector extends DependencyCollectorDelegate {
68 public static final String NAME = "df";
69
70 @Inject
71 public DfDependencyCollector(
72 RemoteRepositoryManager remoteRepositoryManager,
73 ArtifactDescriptorReader artifactDescriptorReader,
74 VersionRangeResolver versionRangeResolver) {
75 super(remoteRepositoryManager, artifactDescriptorReader, versionRangeResolver);
76 }
77
78 @SuppressWarnings("checkstyle:parameternumber")
79 @Override
80 protected void doCollectDependencies(
81 RepositorySystemSession session,
82 RequestTrace trace,
83 DataPool pool,
84 DefaultDependencyCollectionContext context,
85 DefaultVersionFilterContext versionContext,
86 CollectRequest request,
87 DependencyNode node,
88 List<RemoteRepository> repositories,
89 List<Dependency> dependencies,
90 List<Dependency> managedDependencies,
91 Results results) {
92 NodeStack nodes = new NodeStack();
93 nodes.push(node);
94
95 Args args = new Args(session, pool, nodes, context, versionContext, request);
96
97 process(
98 args,
99 trace,
100 results,
101 dependencies,
102 repositories,
103 session.getDependencySelector() != null
104 ? session.getDependencySelector().deriveChildSelector(context)
105 : null,
106 session.getDependencyManager() != null
107 ? session.getDependencyManager().deriveChildManager(context)
108 : null,
109 session.getDependencyTraverser() != null
110 ? session.getDependencyTraverser().deriveChildTraverser(context)
111 : null,
112 session.getVersionFilter() != null ? session.getVersionFilter().deriveChildFilter(context) : null);
113 }
114
115 @SuppressWarnings("checkstyle:parameternumber")
116 private void process(
117 final Args args,
118 RequestTrace trace,
119 Results results,
120 List<Dependency> dependencies,
121 List<RemoteRepository> repositories,
122 DependencySelector depSelector,
123 DependencyManager depManager,
124 DependencyTraverser depTraverser,
125 VersionFilter verFilter) {
126 for (Dependency dependency : dependencies) {
127 processDependency(
128 args, trace, results, repositories, depSelector, depManager, depTraverser, verFilter, dependency);
129 }
130 }
131
132 @SuppressWarnings("checkstyle:parameternumber")
133 private void processDependency(
134 Args args,
135 RequestTrace trace,
136 Results results,
137 List<RemoteRepository> repositories,
138 DependencySelector depSelector,
139 DependencyManager depManager,
140 DependencyTraverser depTraverser,
141 VersionFilter verFilter,
142 Dependency dependency) {
143
144 List<Artifact> relocations = Collections.emptyList();
145 processDependency(
146 args,
147 trace,
148 results,
149 repositories,
150 depSelector,
151 depManager,
152 depTraverser,
153 verFilter,
154 dependency,
155 relocations,
156 false);
157 }
158
159 @SuppressWarnings("checkstyle:parameternumber")
160 private void processDependency(
161 Args args,
162 RequestTrace parent,
163 Results results,
164 List<RemoteRepository> repositories,
165 DependencySelector depSelector,
166 DependencyManager depManager,
167 DependencyTraverser depTraverser,
168 VersionFilter verFilter,
169 Dependency dependency,
170 List<Artifact> relocations,
171 boolean disableVersionManagement) {
172 if (depSelector != null && !depSelector.selectDependency(dependency)) {
173 return;
174 }
175
176 RequestTrace trace = collectStepTrace(parent, args.request.getRequestContext(), args.nodes.nodes, dependency);
177 PremanagedDependency preManaged =
178 PremanagedDependency.create(depManager, dependency, disableVersionManagement, args.premanagedState);
179 dependency = preManaged.getManagedDependency();
180
181 boolean noDescriptor = isLackingDescriptor(dependency.getArtifact());
182
183 boolean traverse = !noDescriptor && (depTraverser == null || depTraverser.traverseDependency(dependency));
184
185 List<? extends Version> versions;
186 VersionRangeResult rangeResult;
187 try {
188 VersionRangeRequest rangeRequest =
189 createVersionRangeRequest(args.request.getRequestContext(), trace, repositories, dependency);
190
191 rangeResult = cachedResolveRangeResult(rangeRequest, args.pool, args.session);
192
193 versions = filterVersions(dependency, rangeResult, verFilter, args.versionContext);
194 } catch (VersionRangeResolutionException e) {
195 results.addException(dependency, e, args.nodes.nodes);
196 return;
197 }
198
199 for (Version version : versions) {
200 Artifact originalArtifact = dependency.getArtifact().setVersion(version.toString());
201 Dependency d = dependency.setArtifact(originalArtifact);
202
203 ArtifactDescriptorRequest descriptorRequest =
204 createArtifactDescriptorRequest(args.request.getRequestContext(), trace, repositories, d);
205
206 final ArtifactDescriptorResult descriptorResult =
207 getArtifactDescriptorResult(args, results, noDescriptor, d, descriptorRequest);
208 if (descriptorResult != null) {
209 d = d.setArtifact(descriptorResult.getArtifact());
210
211 DependencyNode node = args.nodes.top();
212
213 int cycleEntry = DefaultDependencyCycle.find(args.nodes.nodes, d.getArtifact());
214 if (cycleEntry >= 0) {
215 results.addCycle(args.nodes.nodes, cycleEntry, d);
216 DependencyNode cycleNode = args.nodes.get(cycleEntry);
217 if (cycleNode.getDependency() != null) {
218 DefaultDependencyNode child = createDependencyNode(
219 relocations, preManaged, rangeResult, version, d, descriptorResult, cycleNode);
220 node.getChildren().add(child);
221 continue;
222 }
223 }
224
225 if (!descriptorResult.getRelocations().isEmpty()) {
226 boolean disableVersionManagementSubsequently =
227 originalArtifact.getGroupId().equals(d.getArtifact().getGroupId())
228 && originalArtifact
229 .getArtifactId()
230 .equals(d.getArtifact().getArtifactId());
231
232 processDependency(
233 args,
234 parent,
235 results,
236 repositories,
237 depSelector,
238 depManager,
239 depTraverser,
240 verFilter,
241 d,
242 descriptorResult.getRelocations(),
243 disableVersionManagementSubsequently);
244 return;
245 } else {
246 d = args.pool.intern(d.setArtifact(args.pool.intern(d.getArtifact())));
247
248 List<RemoteRepository> repos =
249 getRemoteRepositories(rangeResult.getRepository(version), repositories);
250
251 DefaultDependencyNode child = createDependencyNode(
252 relocations,
253 preManaged,
254 rangeResult,
255 version,
256 d,
257 descriptorResult.getAliases(),
258 repos,
259 args.request.getRequestContext());
260
261 node.getChildren().add(child);
262
263 boolean recurse =
264 traverse && !descriptorResult.getDependencies().isEmpty();
265 if (recurse) {
266 doRecurse(
267 args,
268 parent,
269 results,
270 repositories,
271 depSelector,
272 depManager,
273 depTraverser,
274 verFilter,
275 d,
276 descriptorResult,
277 child);
278 }
279 }
280 } else {
281 DependencyNode node = args.nodes.top();
282 List<RemoteRepository> repos = getRemoteRepositories(rangeResult.getRepository(version), repositories);
283 DefaultDependencyNode child = createDependencyNode(
284 relocations,
285 preManaged,
286 rangeResult,
287 version,
288 d,
289 null,
290 repos,
291 args.request.getRequestContext());
292 node.getChildren().add(child);
293 }
294 }
295 }
296
297 @SuppressWarnings("checkstyle:parameternumber")
298 private void doRecurse(
299 Args args,
300 RequestTrace trace,
301 Results results,
302 List<RemoteRepository> repositories,
303 DependencySelector depSelector,
304 DependencyManager depManager,
305 DependencyTraverser depTraverser,
306 VersionFilter verFilter,
307 Dependency d,
308 ArtifactDescriptorResult descriptorResult,
309 DefaultDependencyNode child) {
310 DefaultDependencyCollectionContext context = args.collectionContext;
311 context.set(d, descriptorResult.getManagedDependencies());
312
313 DependencySelector childSelector = depSelector != null ? depSelector.deriveChildSelector(context) : null;
314 DependencyManager childManager = depManager != null ? depManager.deriveChildManager(context) : null;
315 DependencyTraverser childTraverser = depTraverser != null ? depTraverser.deriveChildTraverser(context) : null;
316 VersionFilter childFilter = verFilter != null ? verFilter.deriveChildFilter(context) : null;
317
318 final List<RemoteRepository> childRepos = args.ignoreRepos
319 ? repositories
320 : remoteRepositoryManager.aggregateRepositories(
321 args.session, repositories, descriptorResult.getRepositories(), true);
322
323 Object key =
324 args.pool.toKey(d.getArtifact(), childRepos, childSelector, childManager, childTraverser, childFilter);
325
326 List<DependencyNode> children = args.pool.getChildren(key);
327 if (children == null) {
328 args.pool.putChildren(key, child.getChildren());
329
330 args.nodes.push(child);
331
332 process(
333 args,
334 trace,
335 results,
336 descriptorResult.getDependencies(),
337 childRepos,
338 childSelector,
339 childManager,
340 childTraverser,
341 childFilter);
342
343 args.nodes.pop();
344 } else {
345 child.setChildren(children);
346 }
347 }
348
349 private ArtifactDescriptorResult getArtifactDescriptorResult(
350 Args args,
351 Results results,
352 boolean noDescriptor,
353 Dependency d,
354 ArtifactDescriptorRequest descriptorRequest) {
355 return noDescriptor
356 ? new ArtifactDescriptorResult(descriptorRequest)
357 : resolveCachedArtifactDescriptor(args.pool, descriptorRequest, args.session, d, results, args);
358 }
359
360 private ArtifactDescriptorResult resolveCachedArtifactDescriptor(
361 DataPool pool,
362 ArtifactDescriptorRequest descriptorRequest,
363 RepositorySystemSession session,
364 Dependency d,
365 Results results,
366 Args args) {
367 Object key = pool.toKey(descriptorRequest);
368 ArtifactDescriptorResult descriptorResult = pool.getDescriptor(key, descriptorRequest);
369 if (descriptorResult == null) {
370 try {
371 descriptorResult = descriptorReader.readArtifactDescriptor(session, descriptorRequest);
372 pool.putDescriptor(key, descriptorResult);
373 } catch (ArtifactDescriptorException e) {
374 results.addException(d, e, args.nodes.nodes);
375 pool.putDescriptor(key, e);
376 return null;
377 }
378
379 } else if (descriptorResult == DataPool.NO_DESCRIPTOR) {
380 return null;
381 }
382
383 return descriptorResult;
384 }
385
386 static class Args {
387
388 final RepositorySystemSession session;
389
390 final boolean ignoreRepos;
391
392 final boolean premanagedState;
393
394 final DataPool pool;
395
396 final NodeStack nodes;
397
398 final DefaultDependencyCollectionContext collectionContext;
399
400 final DefaultVersionFilterContext versionContext;
401
402 final CollectRequest request;
403
404 Args(
405 RepositorySystemSession session,
406 DataPool pool,
407 NodeStack nodes,
408 DefaultDependencyCollectionContext collectionContext,
409 DefaultVersionFilterContext versionContext,
410 CollectRequest request) {
411 this.session = session;
412 this.request = request;
413 this.ignoreRepos = session.isIgnoreArtifactDescriptorRepositories();
414 this.premanagedState = ConfigUtils.getBoolean(session, false, DependencyManagerUtils.CONFIG_PROP_VERBOSE);
415 this.pool = pool;
416 this.nodes = nodes;
417 this.collectionContext = collectionContext;
418 this.versionContext = versionContext;
419 }
420 }
421 }