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