1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.util.graph.manager;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.HashMap;
24 import java.util.LinkedHashSet;
25 import java.util.Objects;
26
27 import org.eclipse.aether.artifact.Artifact;
28 import org.eclipse.aether.collection.DependencyCollectionContext;
29 import org.eclipse.aether.collection.DependencyManagement;
30 import org.eclipse.aether.collection.DependencyManager;
31 import org.eclipse.aether.graph.Dependency;
32 import org.eclipse.aether.graph.Exclusion;
33 import org.eclipse.aether.scope.ScopeManager;
34 import org.eclipse.aether.scope.SystemDependencyScope;
35
36 import static java.util.Objects.requireNonNull;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 public abstract class AbstractDependencyManager implements DependencyManager {
108
109 protected final ArrayList<AbstractDependencyManager> path;
110
111
112 protected final int depth;
113
114
115 protected final int deriveUntil;
116
117
118 protected final int applyFrom;
119
120
121 protected final MMap<Key, String> managedVersions;
122
123
124 protected final MMap<Key, String> managedScopes;
125
126
127 protected final MMap<Key, Boolean> managedOptionals;
128
129
130 protected final MMap<Key, String> managedLocalPaths;
131
132
133 protected final MMap<Key, Holder<Collection<Exclusion>>> managedExclusions;
134
135
136 protected final SystemDependencyScope systemDependencyScope;
137
138
139 private final int hashCode;
140
141
142
143
144
145
146
147
148
149 protected AbstractDependencyManager(int deriveUntil, int applyFrom, ScopeManager scopeManager) {
150 this(
151 new ArrayList<>(),
152 0,
153 deriveUntil,
154 applyFrom,
155 null,
156 null,
157 null,
158 null,
159 null,
160 scopeManager != null
161 ? scopeManager.getSystemDependencyScope().orElse(null)
162 : SystemDependencyScope.LEGACY);
163 }
164
165 @SuppressWarnings("checkstyle:ParameterNumber")
166 protected AbstractDependencyManager(
167 ArrayList<AbstractDependencyManager> path,
168 int depth,
169 int deriveUntil,
170 int applyFrom,
171 MMap<Key, String> managedVersions,
172 MMap<Key, String> managedScopes,
173 MMap<Key, Boolean> managedOptionals,
174 MMap<Key, String> managedLocalPaths,
175 MMap<Key, Holder<Collection<Exclusion>>> managedExclusions,
176 SystemDependencyScope systemDependencyScope) {
177 this.path = path;
178 this.depth = depth;
179 this.deriveUntil = deriveUntil;
180 this.applyFrom = applyFrom;
181 this.managedVersions = managedVersions;
182 this.managedScopes = managedScopes;
183 this.managedOptionals = managedOptionals;
184 this.managedLocalPaths = managedLocalPaths;
185 this.managedExclusions = managedExclusions;
186
187 this.systemDependencyScope = systemDependencyScope;
188
189
190 this.hashCode = Objects.hash(path, depth, managedVersions, managedScopes, managedOptionals, managedExclusions);
191 }
192
193 protected abstract DependencyManager newInstance(
194 MMap<Key, String> managedVersions,
195 MMap<Key, String> managedScopes,
196 MMap<Key, Boolean> managedOptionals,
197 MMap<Key, String> managedLocalPaths,
198 MMap<Key, Holder<Collection<Exclusion>>> managedExclusions);
199
200 private boolean containsManagedVersion(Key key) {
201 for (AbstractDependencyManager ancestor : path) {
202 if (ancestor.managedVersions != null && ancestor.managedVersions.containsKey(key)) {
203 return true;
204 }
205 }
206 return managedVersions != null && managedVersions.containsKey(key);
207 }
208
209 private String getManagedVersion(Key key) {
210 for (AbstractDependencyManager ancestor : path) {
211 if (ancestor.managedVersions != null && ancestor.managedVersions.containsKey(key)) {
212 return ancestor.managedVersions.get(key);
213 }
214 }
215 if (depth == 1 && managedVersions != null && managedVersions.containsKey(key)) {
216 return managedVersions.get(key);
217 }
218 return null;
219 }
220
221 private boolean containsManagedScope(Key key) {
222 for (AbstractDependencyManager ancestor : path) {
223 if (ancestor.managedScopes != null && ancestor.managedScopes.containsKey(key)) {
224 return true;
225 }
226 }
227 return managedScopes != null && managedScopes.containsKey(key);
228 }
229
230 private String getManagedScope(Key key) {
231 for (AbstractDependencyManager ancestor : path) {
232 if (ancestor.managedScopes != null && ancestor.managedScopes.containsKey(key)) {
233 return ancestor.managedScopes.get(key);
234 }
235 }
236 if (depth == 1 && managedScopes != null && managedScopes.containsKey(key)) {
237 return managedScopes.get(key);
238 }
239 return null;
240 }
241
242 private boolean containsManagedOptional(Key key) {
243 for (AbstractDependencyManager ancestor : path) {
244 if (ancestor.managedOptionals != null && ancestor.managedOptionals.containsKey(key)) {
245 return true;
246 }
247 }
248 return managedOptionals != null && managedOptionals.containsKey(key);
249 }
250
251 private Boolean getManagedOptional(Key key) {
252 for (AbstractDependencyManager ancestor : path) {
253 if (ancestor.managedOptionals != null && ancestor.managedOptionals.containsKey(key)) {
254 return ancestor.managedOptionals.get(key);
255 }
256 }
257 if (depth == 1 && managedOptionals != null && managedOptionals.containsKey(key)) {
258 return managedOptionals.get(key);
259 }
260 return null;
261 }
262
263 private boolean containsManagedLocalPath(Key key) {
264 for (AbstractDependencyManager ancestor : path) {
265 if (ancestor.managedLocalPaths != null && ancestor.managedLocalPaths.containsKey(key)) {
266 return true;
267 }
268 }
269 return managedLocalPaths != null && managedLocalPaths.containsKey(key);
270 }
271
272
273
274
275
276
277
278
279 private String getManagedLocalPath(Key key) {
280 for (AbstractDependencyManager ancestor : path) {
281 if (ancestor.managedLocalPaths != null && ancestor.managedLocalPaths.containsKey(key)) {
282 return ancestor.managedLocalPaths.get(key);
283 }
284 }
285 if (managedLocalPaths != null && managedLocalPaths.containsKey(key)) {
286 return managedLocalPaths.get(key);
287 }
288 return null;
289 }
290
291
292
293
294
295
296
297
298
299 private Collection<Exclusion> getManagedExclusions(Key key) {
300 ArrayList<Exclusion> result = new ArrayList<>();
301 for (AbstractDependencyManager ancestor : path) {
302 if (ancestor.managedExclusions != null && ancestor.managedExclusions.containsKey(key)) {
303 result.addAll(ancestor.managedExclusions.get(key).value);
304 }
305 }
306 if (managedExclusions != null && managedExclusions.containsKey(key)) {
307 result.addAll(managedExclusions.get(key).value);
308 }
309 return result.isEmpty() ? null : result;
310 }
311
312 @Override
313 public DependencyManager deriveChildManager(DependencyCollectionContext context) {
314 requireNonNull(context, "context cannot be null");
315 if (!isDerived()) {
316 return this;
317 }
318
319 MMap<Key, String> managedVersions = null;
320 MMap<Key, String> managedScopes = null;
321 MMap<Key, Boolean> managedOptionals = null;
322 MMap<Key, String> managedLocalPaths = null;
323 MMap<Key, Holder<Collection<Exclusion>>> managedExclusions = null;
324
325 for (Dependency managedDependency : context.getManagedDependencies()) {
326 Artifact artifact = managedDependency.getArtifact();
327 Key key = new Key(artifact);
328
329 String version = artifact.getVersion();
330 if (!version.isEmpty() && !containsManagedVersion(key)) {
331 if (managedVersions == null) {
332 managedVersions = MMap.emptyNotDone();
333 }
334 managedVersions.put(key, version);
335 }
336
337 if (isInheritedDerived()) {
338 String scope = managedDependency.getScope();
339 if (!scope.isEmpty() && !containsManagedScope(key)) {
340 if (managedScopes == null) {
341 managedScopes = MMap.emptyNotDone();
342 }
343 managedScopes.put(key, scope);
344 }
345
346 Boolean optional = managedDependency.getOptional();
347 if (optional != null && !containsManagedOptional(key)) {
348 if (managedOptionals == null) {
349 managedOptionals = MMap.emptyNotDone();
350 }
351 managedOptionals.put(key, optional);
352 }
353 }
354
355 String localPath = systemDependencyScope == null
356 ? null
357 : systemDependencyScope.getSystemPath(managedDependency.getArtifact());
358 if (localPath != null && !containsManagedLocalPath(key)) {
359 if (managedLocalPaths == null) {
360 managedLocalPaths = MMap.emptyNotDone();
361 }
362 managedLocalPaths.put(key, localPath);
363 }
364
365 Collection<Exclusion> exclusions = managedDependency.getExclusions();
366 if (!exclusions.isEmpty()) {
367 if (managedExclusions == null) {
368 managedExclusions = MMap.emptyNotDone();
369 }
370 Holder<Collection<Exclusion>> managed = managedExclusions.get(key);
371 if (managed != null) {
372 ArrayList<Exclusion> ex = new ArrayList<>(managed.getValue());
373 ex.addAll(exclusions);
374 managed = new Holder<>(ex);
375 managedExclusions.put(key, managed);
376 } else {
377 managedExclusions.put(key, new Holder<>(exclusions));
378 }
379 }
380 }
381
382 return newInstance(
383 managedVersions != null ? managedVersions.done() : null,
384 managedScopes != null ? managedScopes.done() : null,
385 managedOptionals != null ? managedOptionals.done() : null,
386 managedLocalPaths != null ? managedLocalPaths.done() : null,
387 managedExclusions != null ? managedExclusions.done() : null);
388 }
389
390 @Override
391 public DependencyManagement manageDependency(Dependency dependency) {
392 requireNonNull(dependency, "dependency cannot be null");
393 DependencyManagement management = null;
394 Key key = new Key(dependency.getArtifact());
395
396 if (isApplied()) {
397 String version = getManagedVersion(key);
398
399
400 if (version != null) {
401 management = new DependencyManagement();
402 management.setVersion(version);
403 }
404
405 String scope = getManagedScope(key);
406
407
408 if (scope != null) {
409 if (management == null) {
410 management = new DependencyManagement();
411 }
412 management.setScope(scope);
413
414 if (systemDependencyScope != null
415 && !systemDependencyScope.is(scope)
416 && systemDependencyScope.getSystemPath(dependency.getArtifact()) != null) {
417 HashMap<String, String> properties =
418 new HashMap<>(dependency.getArtifact().getProperties());
419 systemDependencyScope.setSystemPath(properties, null);
420 management.setProperties(properties);
421 }
422 }
423
424
425
426 if (systemDependencyScope != null
427 && (scope != null && systemDependencyScope.is(scope)
428 || (scope == null && systemDependencyScope.is(dependency.getScope())))) {
429 String localPath = getManagedLocalPath(key);
430 if (localPath != null) {
431 if (management == null) {
432 management = new DependencyManagement();
433 }
434 HashMap<String, String> properties =
435 new HashMap<>(dependency.getArtifact().getProperties());
436 systemDependencyScope.setSystemPath(properties, localPath);
437 management.setProperties(properties);
438 }
439 }
440
441
442
443 Boolean optional = getManagedOptional(key);
444 if (optional != null) {
445 if (management == null) {
446 management = new DependencyManagement();
447 }
448 management.setOptional(optional);
449 }
450 }
451
452
453
454
455
456
457 Collection<Exclusion> exclusions = getManagedExclusions(key);
458 if (exclusions != null) {
459 if (management == null) {
460 management = new DependencyManagement();
461 }
462 Collection<Exclusion> result = new LinkedHashSet<>(dependency.getExclusions());
463 result.addAll(exclusions);
464 management.setExclusions(result);
465 }
466
467 return management;
468 }
469
470
471
472
473 protected boolean isDerived() {
474 return depth < deriveUntil;
475 }
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501 protected boolean isInheritedDerived() {
502 return isDerived();
503 }
504
505
506
507
508 protected boolean isApplied() {
509 return depth >= applyFrom;
510 }
511
512 @Override
513 public boolean equals(Object obj) {
514 if (this == obj) {
515 return true;
516 } else if (null == obj || !getClass().equals(obj.getClass())) {
517 return false;
518 }
519
520 AbstractDependencyManager that = (AbstractDependencyManager) obj;
521
522 return Objects.equals(path, that.path)
523 && depth == that.depth
524 && Objects.equals(managedVersions, that.managedVersions)
525 && Objects.equals(managedScopes, that.managedScopes)
526 && Objects.equals(managedOptionals, that.managedOptionals)
527 && Objects.equals(managedExclusions, that.managedExclusions);
528 }
529
530 @Override
531 public int hashCode() {
532 return hashCode;
533 }
534
535
536
537
538
539 protected static class Key {
540 private final Artifact artifact;
541 private final int hashCode;
542
543
544
545
546
547
548 Key(Artifact artifact) {
549 this.artifact = artifact;
550 this.hashCode = Objects.hash(
551 artifact.getArtifactId(), artifact.getGroupId(), artifact.getExtension(), artifact.getClassifier());
552 }
553
554 @Override
555 public boolean equals(Object obj) {
556 if (obj == this) {
557 return true;
558 } else if (!(obj instanceof Key)) {
559 return false;
560 }
561 Key that = (Key) obj;
562 return artifact.getArtifactId().equals(that.artifact.getArtifactId())
563 && artifact.getGroupId().equals(that.artifact.getGroupId())
564 && artifact.getExtension().equals(that.artifact.getExtension())
565 && artifact.getClassifier().equals(that.artifact.getClassifier());
566 }
567
568 @Override
569 public int hashCode() {
570 return hashCode;
571 }
572
573 @Override
574 public String toString() {
575 return String.valueOf(artifact);
576 }
577 }
578
579
580
581
582
583
584 protected static class Holder<T> {
585 private final T value;
586 private final int hashCode;
587
588 Holder(T value) {
589 this.value = requireNonNull(value);
590 this.hashCode = Objects.hash(value);
591 }
592
593 public T getValue() {
594 return value;
595 }
596
597 @Override
598 public boolean equals(Object o) {
599 if (!(o instanceof Holder)) {
600 return false;
601 }
602 Holder<?> holder = (Holder<?>) o;
603 return Objects.equals(value, holder.value);
604 }
605
606 @Override
607 public int hashCode() {
608 return hashCode;
609 }
610 }
611 }