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