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