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;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.concurrent.atomic.AtomicReference;
32
33 import org.eclipse.aether.DefaultRepositorySystemSession;
34 import org.eclipse.aether.RepositorySystemSession;
35 import org.eclipse.aether.artifact.Artifact;
36 import org.eclipse.aether.artifact.ArtifactProperties;
37 import org.eclipse.aether.artifact.DefaultArtifact;
38 import org.eclipse.aether.collection.CollectRequest;
39 import org.eclipse.aether.collection.CollectResult;
40 import org.eclipse.aether.collection.DependencyCollectionContext;
41 import org.eclipse.aether.collection.DependencyCollectionException;
42 import org.eclipse.aether.collection.DependencyManagement;
43 import org.eclipse.aether.collection.DependencyManager;
44 import org.eclipse.aether.graph.DefaultDependencyNode;
45 import org.eclipse.aether.graph.Dependency;
46 import org.eclipse.aether.graph.DependencyCycle;
47 import org.eclipse.aether.graph.DependencyNode;
48 import org.eclipse.aether.graph.Exclusion;
49 import org.eclipse.aether.impl.ArtifactDescriptorReader;
50 import org.eclipse.aether.internal.impl.IniArtifactDescriptorReader;
51 import org.eclipse.aether.internal.test.util.DependencyGraphParser;
52 import org.eclipse.aether.internal.test.util.TestUtils;
53 import org.eclipse.aether.repository.RemoteRepository;
54 import org.eclipse.aether.resolution.ArtifactDescriptorException;
55 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
56 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
57 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
58 import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
59 import org.eclipse.aether.util.graph.manager.DefaultDependencyManager;
60 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
61 import org.eclipse.aether.util.graph.manager.TransitiveDependencyManager;
62 import org.eclipse.aether.util.graph.transformer.ConflictResolver;
63 import org.eclipse.aether.util.graph.transformer.JavaScopeDeriver;
64 import org.eclipse.aether.util.graph.transformer.JavaScopeSelector;
65 import org.eclipse.aether.util.graph.transformer.NearestVersionSelector;
66 import org.eclipse.aether.util.graph.transformer.SimpleOptionalitySelector;
67 import org.eclipse.aether.util.graph.version.HighestVersionFilter;
68 import org.junit.jupiter.api.BeforeEach;
69 import org.junit.jupiter.api.Test;
70
71 import static java.util.Collections.singletonList;
72 import static java.util.Objects.requireNonNull;
73 import static org.junit.jupiter.api.Assertions.*;
74
75
76
77
78 public abstract class DependencyCollectorDelegateTestSupport {
79
80 protected DefaultRepositorySystemSession session;
81
82 protected DependencyGraphParser parser;
83
84 protected RemoteRepository repository;
85
86 protected DependencyCollectorDelegate collector;
87
88 protected IniArtifactDescriptorReader newReader(String prefix) {
89 return new IniArtifactDescriptorReader("artifact-descriptions/" + prefix);
90 }
91
92 protected Dependency newDep(String coords) {
93 return newDep(coords, "");
94 }
95
96 protected Dependency newDep(String coords, String scope) {
97 return new Dependency(new DefaultArtifact(coords), scope);
98 }
99
100 @BeforeEach
101 void setup() {
102 session = TestUtils.newSession();
103 parser = new DependencyGraphParser("artifact-descriptions/");
104 repository = new RemoteRepository.Builder("id", "default", "file:///").build();
105 collector = setupCollector(newReader(""));
106 }
107
108 protected abstract DependencyCollectorDelegate setupCollector(ArtifactDescriptorReader artifactDescriptorReader);
109
110 private static void assertEqualSubtree(DependencyNode expected, DependencyNode actual) {
111 assertEqualSubtree(expected, actual, new LinkedList<>());
112 }
113
114 private static void assertEqualSubtree(
115 DependencyNode expected, DependencyNode actual, LinkedList<DependencyNode> parents) {
116 assertEquals(expected.getDependency(), actual.getDependency(), "path: " + parents);
117
118 if (actual.getDependency() != null) {
119 Artifact artifact = actual.getDependency().getArtifact();
120 for (DependencyNode parent : parents) {
121 if (parent.getDependency() != null
122 && artifact.equals(parent.getDependency().getArtifact())) {
123 return;
124 }
125 }
126 }
127
128 parents.addLast(expected);
129
130 assertEquals(
131 expected.getChildren().size(),
132 actual.getChildren().size(),
133 "path: " + parents + ", expected: " + expected.getChildren() + ", actual: " + actual.getChildren());
134
135 Iterator<DependencyNode> iterator1 = expected.getChildren().iterator();
136 Iterator<DependencyNode> iterator2 = actual.getChildren().iterator();
137
138 while (iterator1.hasNext()) {
139 assertEqualSubtree(iterator1.next(), iterator2.next(), parents);
140 }
141
142 parents.removeLast();
143 }
144
145 protected Dependency dep(DependencyNode root, int... coords) {
146 return path(root, coords).getDependency();
147 }
148
149 protected DependencyNode path(DependencyNode root, int... coords) {
150 try {
151 DependencyNode node = root;
152 for (int coord : coords) {
153 node = node.getChildren().get(coord);
154 }
155
156 return node;
157 } catch (IndexOutOfBoundsException | NullPointerException e) {
158 throw new IllegalArgumentException("illegal coordinates for child", e);
159 }
160 }
161
162 @Test
163 void testInterruption() throws Exception {
164 Dependency dependency = newDep("gid:aid:ext:ver", "compile");
165 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
166 AtomicReference<Object> cause = new AtomicReference<>(null);
167 Thread t = new Thread(() -> {
168 Thread.currentThread().interrupt();
169 try {
170 collector.collectDependencies(session, request);
171 fail("We should throw");
172 } catch (DependencyCollectionException e) {
173 cause.set(e.getCause());
174 }
175 });
176 t.start();
177 t.join();
178 assertTrue(cause.get() instanceof InterruptedException, String.valueOf(cause.get()));
179 }
180
181 @Test
182 void testSimpleCollection() throws DependencyCollectionException {
183 Dependency dependency = newDep("gid:aid:ext:ver", "compile");
184 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
185 CollectResult result = collector.collectDependencies(session, request);
186
187 assertEquals(0, result.getExceptions().size());
188
189 DependencyNode root = result.getRoot();
190 Dependency newDependency = root.getDependency();
191
192 assertEquals(dependency, newDependency);
193 assertEquals(dependency.getArtifact(), newDependency.getArtifact());
194
195 assertEquals(1, root.getChildren().size());
196
197 Dependency expect = newDep("gid:aid2:ext:ver", "compile");
198 assertEquals(expect, root.getChildren().get(0).getDependency());
199 }
200
201 @Test
202 void testMissingDependencyDescription() {
203 CollectRequest request = new CollectRequest(newDep("missing:description:ext:ver"), singletonList(repository));
204 try {
205 collector.collectDependencies(session, request);
206 fail("expected exception");
207 } catch (DependencyCollectionException e) {
208 CollectResult result = e.getResult();
209 assertSame(request, result.getRequest());
210 assertNotNull(result.getExceptions());
211 assertEquals(1, result.getExceptions().size());
212
213 assertTrue(result.getExceptions().get(0) instanceof ArtifactDescriptorException);
214
215 assertEquals(request.getRoot(), result.getRoot().getDependency());
216 }
217 }
218
219 @Test
220 void testDuplicates() throws DependencyCollectionException {
221 Dependency dependency = newDep("duplicate:transitive:ext:dependency");
222 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
223
224 CollectResult result = collector.collectDependencies(session, request);
225
226 assertEquals(0, result.getExceptions().size());
227
228 DependencyNode root = result.getRoot();
229 Dependency newDependency = root.getDependency();
230
231 assertEquals(dependency, newDependency);
232 assertEquals(dependency.getArtifact(), newDependency.getArtifact());
233
234 assertEquals(2, root.getChildren().size());
235
236 Dependency dep = newDep("gid:aid:ext:ver", "compile");
237 assertEquals(dep, dep(root, 0));
238
239 dep = newDep("gid:aid2:ext:ver", "compile");
240 assertEquals(dep, dep(root, 1));
241 assertEquals(dep, dep(root, 0, 0));
242 assertEquals(dep(root, 1), dep(root, 0, 0));
243 }
244
245 @Test
246 void testEqualSubtree() throws IOException, DependencyCollectionException {
247 DependencyNode root = parser.parseResource("expectedSubtreeComparisonResult.txt");
248 Dependency dependency = root.getDependency();
249 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
250
251 CollectResult result = collector.collectDependencies(session, request);
252 assertEqualSubtree(root, result.getRoot());
253 }
254
255 @Test
256 void testCyclicDependencies() throws Exception {
257 DependencyNode root = parser.parseResource("cycle.txt");
258 CollectRequest request = new CollectRequest(root.getDependency(), singletonList(repository));
259 CollectResult result = collector.collectDependencies(session, request);
260 assertEqualSubtree(root, result.getRoot());
261 }
262
263 @Test
264 void testCyclicDependenciesBig() throws Exception {
265 CollectRequest request = new CollectRequest(newDep("1:2:pom:5.50-SNAPSHOT"), singletonList(repository));
266 collector = setupCollector(newReader("cycle-big/"));
267 CollectResult result = collector.collectDependencies(session, request);
268 assertNotNull(result.getRoot());
269
270 }
271
272 @Test
273 void testCyclicProjects() throws Exception {
274 CollectRequest request = new CollectRequest(newDep("test:a:2"), singletonList(repository));
275 collector = setupCollector(newReader("versionless-cycle/"));
276 CollectResult result = collector.collectDependencies(session, request);
277 DependencyNode root = result.getRoot();
278 DependencyNode a1 = path(root, 0, 0);
279 assertEquals("a", a1.getArtifact().getArtifactId());
280 assertEquals("1", a1.getArtifact().getVersion());
281 for (DependencyNode child : a1.getChildren()) {
282 assertNotEquals("1", child.getArtifact().getVersion());
283 }
284
285 assertEquals(1, result.getCycles().size());
286 DependencyCycle cycle = result.getCycles().get(0);
287 assertEquals(Collections.emptyList(), cycle.getPrecedingDependencies());
288 assertEquals(
289 Arrays.asList(root.getDependency(), path(root, 0).getDependency(), a1.getDependency()),
290 cycle.getCyclicDependencies());
291 }
292
293 @Test
294 void testCyclicProjects_ConsiderLabelOfRootlessGraph() throws Exception {
295 Dependency dep = newDep("gid:aid:ver", "compile");
296 CollectRequest request = new CollectRequest()
297 .addDependency(dep)
298 .addRepository(repository)
299 .setRootArtifact(dep.getArtifact());
300 CollectResult result = collector.collectDependencies(session, request);
301 DependencyNode root = result.getRoot();
302 DependencyNode a1 = root.getChildren().get(0);
303 assertEquals("aid", a1.getArtifact().getArtifactId());
304 assertEquals("ver", a1.getArtifact().getVersion());
305 DependencyNode a2 = a1.getChildren().get(0);
306 assertEquals("aid2", a2.getArtifact().getArtifactId());
307 assertEquals("ver", a2.getArtifact().getVersion());
308
309 assertEquals(1, result.getCycles().size());
310 DependencyCycle cycle = result.getCycles().get(0);
311 assertEquals(Collections.emptyList(), cycle.getPrecedingDependencies());
312 assertEquals(
313 Arrays.asList(new Dependency(dep.getArtifact(), null), a1.getDependency()),
314 cycle.getCyclicDependencies());
315 }
316
317 @Test
318 void testPartialResultOnError() throws IOException {
319 DependencyNode root = parser.parseResource("expectedPartialSubtreeOnError.txt");
320
321 Dependency dependency = root.getDependency();
322 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
323
324 CollectResult result;
325 try {
326 collector.collectDependencies(session, request);
327 fail("expected exception ");
328 } catch (DependencyCollectionException e) {
329 result = e.getResult();
330
331 assertSame(request, result.getRequest());
332 assertNotNull(result.getExceptions());
333 assertEquals(1, result.getExceptions().size());
334
335 assertTrue(result.getExceptions().get(0) instanceof ArtifactDescriptorException);
336
337 assertEqualSubtree(root, result.getRoot());
338 }
339 }
340
341 @Test
342 void testCollectMultipleDependencies() throws DependencyCollectionException {
343 Dependency root1 = newDep("gid:aid:ext:ver", "compile");
344 Dependency root2 = newDep("gid:aid2:ext:ver", "compile");
345 List<Dependency> dependencies = Arrays.asList(root1, root2);
346 CollectRequest request = new CollectRequest(dependencies, null, singletonList(repository));
347 CollectResult result = collector.collectDependencies(session, request);
348
349 assertEquals(0, result.getExceptions().size());
350 assertEquals(2, result.getRoot().getChildren().size());
351 assertEquals(root1, dep(result.getRoot(), 0));
352
353 assertEquals(1, path(result.getRoot(), 0).getChildren().size());
354 assertEquals(root2, dep(result.getRoot(), 0, 0));
355
356 assertEquals(0, path(result.getRoot(), 1).getChildren().size());
357 assertEquals(root2, dep(result.getRoot(), 1));
358 }
359
360 @Test
361 void testArtifactDescriptorResolutionNotRestrictedToRepoHostingSelectedVersion() throws Exception {
362 RemoteRepository repo2 = new RemoteRepository.Builder("test", "default", "file:///").build();
363
364 final List<RemoteRepository> repos = new ArrayList<>();
365
366 collector = setupCollector(new ArtifactDescriptorReader() {
367 @Override
368 public ArtifactDescriptorResult readArtifactDescriptor(
369 RepositorySystemSession session, ArtifactDescriptorRequest request) {
370 repos.addAll(request.getRepositories());
371 return new ArtifactDescriptorResult(request);
372 }
373 });
374
375 List<Dependency> dependencies = singletonList(newDep("verrange:parent:jar:1[1,)", "compile"));
376 CollectRequest request = new CollectRequest(dependencies, null, Arrays.asList(repository, repo2));
377 CollectResult result = collector.collectDependencies(session, request);
378
379 assertEquals(0, result.getExceptions().size());
380 assertEquals(2, repos.size());
381 assertEquals("id", repos.get(0).getId());
382 assertEquals("test", repos.get(1).getId());
383 }
384
385 @Test
386 void testManagedVersionScope() throws DependencyCollectionException {
387 Dependency dependency = newDep("managed:aid:ext:ver");
388 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
389
390 session.setDependencyManager(new ClassicDependencyManager());
391
392 CollectResult result = collector.collectDependencies(session, request);
393
394 assertEquals(0, result.getExceptions().size());
395
396 DependencyNode root = result.getRoot();
397
398 assertEquals(dependency, dep(root));
399 assertEquals(dependency.getArtifact(), dep(root).getArtifact());
400
401 assertEquals(1, root.getChildren().size());
402 Dependency expect = newDep("gid:aid:ext:ver", "compile");
403 assertEquals(expect, dep(root, 0));
404
405 assertEquals(1, path(root, 0).getChildren().size());
406 expect = newDep("gid:aid2:ext:managedVersion", "managedScope");
407 assertEquals(expect, dep(root, 0, 0));
408 }
409
410 @Test
411 void testDependencyManagement() throws IOException, DependencyCollectionException {
412 collector = setupCollector(newReader("managed/"));
413
414 DependencyNode root = parser.parseResource("expectedSubtreeComparisonResult.txt");
415 TestDependencyManager depMgmt = new TestDependencyManager();
416 depMgmt.add(dep(root, 0), "managed", null, null);
417 depMgmt.add(dep(root, 0, 1), "managed", "managed", null);
418 depMgmt.add(dep(root, 1), null, null, "managed");
419 session.setDependencyManager(depMgmt);
420
421
422
423 CollectRequest request = new CollectRequest(dep(root), singletonList(repository));
424 CollectResult result = collector.collectDependencies(session, request);
425
426 DependencyNode node = result.getRoot();
427 assertEquals("managed", dep(node, 0, 1).getArtifact().getVersion());
428 assertEquals("managed", dep(node, 0, 1).getScope());
429
430 assertEquals("managed", dep(node, 1).getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null));
431 assertEquals("managed", dep(node, 0, 0).getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null));
432 }
433
434 @Test
435 void testDependencyManagement_VerboseMode() throws Exception {
436 String depId = "gid:aid2:ext";
437 TestDependencyManager depMgmt = new TestDependencyManager();
438 depMgmt.version(depId, "managedVersion");
439 depMgmt.scope(depId, "managedScope");
440 depMgmt.optional(depId, Boolean.TRUE);
441 depMgmt.path(depId, "managedPath");
442 depMgmt.exclusions(depId, new Exclusion("gid", "aid", "*", "*"));
443 session.setDependencyManager(depMgmt);
444 session.setConfigProperty(DependencyManagerUtils.CONFIG_PROP_VERBOSE, Boolean.TRUE);
445
446 CollectRequest request = new CollectRequest().setRoot(newDep("gid:aid:ver"));
447 CollectResult result = collector.collectDependencies(session, request);
448 DependencyNode node = result.getRoot().getChildren().get(0);
449 assertEquals(
450 DependencyNode.MANAGED_VERSION
451 | DependencyNode.MANAGED_SCOPE
452 | DependencyNode.MANAGED_OPTIONAL
453 | DependencyNode.MANAGED_PROPERTIES
454 | DependencyNode.MANAGED_EXCLUSIONS,
455 node.getManagedBits());
456 assertEquals("ver", DependencyManagerUtils.getPremanagedVersion(node));
457 assertEquals("compile", DependencyManagerUtils.getPremanagedScope(node));
458 assertEquals(Boolean.FALSE, DependencyManagerUtils.getPremanagedOptional(node));
459 }
460
461 @Test
462 void testDependencyManagement_TransitiveDependencyManager() throws DependencyCollectionException, IOException {
463 collector = setupCollector(newReader("managed/"));
464 parser = new DependencyGraphParser("artifact-descriptions/managed/");
465 session.setDependencyManager(new TransitiveDependencyManager());
466 final Dependency root = newDep("gid:root:ext:ver", "compile");
467 CollectRequest request = new CollectRequest(root, singletonList(repository));
468 request.addManagedDependency(newDep("gid:root:ext:must-retain-core-management"));
469 CollectResult result = collector.collectDependencies(session, request);
470
471 final DependencyNode expectedTree = parser.parseResource("management-tree.txt");
472 assertEqualSubtree(expectedTree, result.getRoot());
473
474
475 final CollectRequest rootArtifactRequest = new CollectRequest();
476 rootArtifactRequest.setRepositories(singletonList(repository));
477 rootArtifactRequest.setRootArtifact(new DefaultArtifact("gid:root:ext:ver"));
478 rootArtifactRequest.addDependency(newDep("gid:direct:ext:ver", "compile"));
479 rootArtifactRequest.addManagedDependency(newDep("gid:root:ext:must-retain-core-management"));
480 rootArtifactRequest.addManagedDependency(newDep("gid:direct:ext:must-retain-core-management"));
481 rootArtifactRequest.addManagedDependency(newDep("gid:transitive-1:ext:managed-by-root"));
482 session.setDependencyManager(new TransitiveDependencyManager());
483 result = collector.collectDependencies(session, rootArtifactRequest);
484 assertEqualSubtree(expectedTree, toDependencyResult(result.getRoot(), "compile", null));
485 }
486
487 @Test
488 void testDependencyManagement_DefaultDependencyManager() throws DependencyCollectionException, IOException {
489 collector = setupCollector(newReader("managed/"));
490 parser = new DependencyGraphParser("artifact-descriptions/managed/");
491 session.setDependencyManager(new DefaultDependencyManager());
492 final Dependency root = newDep("gid:root:ext:ver", "compile");
493 CollectRequest request = new CollectRequest(root, singletonList(repository));
494 request.addManagedDependency(newDep("gid:root:ext:must-not-manage-root"));
495 request.addManagedDependency(newDep("gid:direct:ext:managed-by-dominant-request"));
496 CollectResult result = collector.collectDependencies(session, request);
497
498 final DependencyNode expectedTree = parser.parseResource("default-management-tree.txt");
499 assertEqualSubtree(expectedTree, result.getRoot());
500
501
502 final CollectRequest rootArtifactRequest = new CollectRequest();
503 rootArtifactRequest.setRepositories(singletonList(repository));
504 rootArtifactRequest.setRootArtifact(new DefaultArtifact("gid:root:ext:ver"));
505 rootArtifactRequest.addDependency(newDep("gid:direct:ext:ver", "compile"));
506 rootArtifactRequest.addManagedDependency(newDep("gid:root:ext:must-not-manage-root"));
507 rootArtifactRequest.addManagedDependency(newDep("gid:direct:ext:managed-by-dominant-request"));
508 rootArtifactRequest.addManagedDependency(newDep("gid:transitive-1:ext:managed-by-root"));
509 session.setDependencyManager(new DefaultDependencyManager());
510 result = collector.collectDependencies(session, rootArtifactRequest);
511 assertEqualSubtree(expectedTree, toDependencyResult(result.getRoot(), "compile", null));
512 }
513
514 @Test
515 void testTransitiveDepsUseRangesDirtyTree() throws DependencyCollectionException, IOException {
516
517
518
519
520
521 DependencyNode root = parser.parseResource(getTransitiveDepsUseRangesDirtyTreeResource());
522 Dependency dependency = root.getDependency();
523 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
524
525 CollectResult result = collector.collectDependencies(session, request);
526 assertEqualSubtree(root, result.getRoot());
527 }
528
529 protected abstract String getTransitiveDepsUseRangesDirtyTreeResource();
530
531 @Test
532 void testTransitiveDepsUseRangesAndRelocationDirtyTree() throws DependencyCollectionException, IOException {
533
534
535
536
537
538 DependencyNode root = parser.parseResource(getTransitiveDepsUseRangesAndRelocationDirtyTreeResource());
539 Dependency dependency = root.getDependency();
540 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
541
542 CollectResult result = collector.collectDependencies(session, request);
543 assertEqualSubtree(root, result.getRoot());
544 }
545
546 protected abstract String getTransitiveDepsUseRangesAndRelocationDirtyTreeResource();
547
548 private DependencyNode toDependencyResult(
549 final DependencyNode root, final String rootScope, final Boolean optional) {
550
551 assertNull(root.getDependency(), "Expected root artifact resolution result.");
552 final DefaultDependencyNode defaultNode =
553 new DefaultDependencyNode(new Dependency(root.getArtifact(), rootScope));
554
555 defaultNode.setChildren(root.getChildren());
556
557 if (optional != null) {
558 defaultNode.setOptional(optional);
559 }
560
561 return defaultNode;
562 }
563
564 @Test
565 void testVersionFilter() throws Exception {
566 session.setVersionFilter(new HighestVersionFilter());
567 CollectRequest request = new CollectRequest().setRoot(newDep("gid:aid:1"));
568 CollectResult result = collector.collectDependencies(session, request);
569 assertEquals(1, result.getRoot().getChildren().size());
570 }
571
572 @Test
573 void testDescriptorDependenciesEmpty() throws Exception {
574 collector = setupCollector(newReader("dependencies-empty/"));
575
576 session.setDependencyGraphTransformer(new ConflictResolver(
577 new NearestVersionSelector(),
578 new JavaScopeSelector(),
579 new SimpleOptionalitySelector(),
580 new JavaScopeDeriver()));
581
582 DependencyNode root = parser.parseResource("expectedSubtreeOnDescriptorDependenciesEmptyLeft.txt");
583 Dependency dependency = root.getDependency();
584 CollectRequest request = new CollectRequest(dependency, singletonList(repository));
585 CollectResult result = collector.collectDependencies(session, request);
586 assertEqualSubtree(root, result.getRoot());
587
588 root = parser.parseResource("expectedSubtreeOnDescriptorDependenciesEmptyRight.txt");
589 dependency = root.getDependency();
590 request = new CollectRequest(dependency, singletonList(repository));
591 result = collector.collectDependencies(session, request);
592 assertEqualSubtree(root, result.getRoot());
593 }
594
595 static class TestDependencyManager implements DependencyManager {
596
597 private final Map<String, String> versions = new HashMap<>();
598
599 private final Map<String, String> scopes = new HashMap<>();
600
601 private final Map<String, Boolean> optionals = new HashMap<>();
602
603 private final Map<String, String> paths = new HashMap<>();
604
605 private final Map<String, Collection<Exclusion>> exclusions = new HashMap<>();
606
607 public void add(Dependency d, String version, String scope, String localPath) {
608 String id = toKey(d);
609 version(id, version);
610 scope(id, scope);
611 path(id, localPath);
612 }
613
614 public void version(String id, String version) {
615 versions.put(id, version);
616 }
617
618 public void scope(String id, String scope) {
619 scopes.put(id, scope);
620 }
621
622 public void optional(String id, Boolean optional) {
623 optionals.put(id, optional);
624 }
625
626 public void path(String id, String path) {
627 paths.put(id, path);
628 }
629
630 public void exclusions(String id, Exclusion... exclusions) {
631 this.exclusions.put(id, exclusions != null ? Arrays.asList(exclusions) : null);
632 }
633
634 @Override
635 public DependencyManagement manageDependency(Dependency dependency) {
636 requireNonNull(dependency, "dependency cannot be null");
637 String id = toKey(dependency);
638 DependencyManagement mgmt = new DependencyManagement();
639 mgmt.setVersion(versions.get(id));
640 mgmt.setScope(scopes.get(id));
641 mgmt.setOptional(optionals.get(id));
642 String path = paths.get(id);
643 if (path != null) {
644 mgmt.setProperties(Collections.singletonMap(ArtifactProperties.LOCAL_PATH, path));
645 }
646 mgmt.setExclusions(exclusions.get(id));
647 return mgmt;
648 }
649
650 private String toKey(Dependency dependency) {
651 return ArtifactIdUtils.toVersionlessId(dependency.getArtifact());
652 }
653
654 @Override
655 public DependencyManager deriveChildManager(DependencyCollectionContext context) {
656 requireNonNull(context, "context cannot be null");
657 return this;
658 }
659 }
660 }