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.scope;
20
21 import java.util.Collection;
22 import java.util.Objects;
23
24 import org.eclipse.aether.Keys;
25 import org.eclipse.aether.collection.DependencyCollectionContext;
26 import org.eclipse.aether.collection.DependencySelector;
27 import org.eclipse.aether.graph.Dependency;
28 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
29
30 import static java.util.Objects.requireNonNull;
31
32
33
34
35
36
37
38
39
40 public final class OptionalDependencySelector implements DependencySelector {
41 public static final Object IGNORED_KEYS = Keys.of(OptionalDependencySelector.class, "ignored");
42 public static final Object UNSELECTED_KEYS = Keys.of(OptionalDependencySelector.class, "unselected");
43
44
45
46
47 public static OptionalDependencySelector fromRoot() {
48 return from(1);
49 }
50
51
52
53
54 public static OptionalDependencySelector fromDirect() {
55 return from(2);
56 }
57
58
59
60
61 public static OptionalDependencySelector from(int applyFrom) {
62 if (applyFrom < 1) {
63 throw new IllegalArgumentException("applyFrom must be non-zero and positive");
64 }
65 return new OptionalDependencySelector(Objects.hash(applyFrom), 0, applyFrom, null, null);
66 }
67
68 private final int seed;
69 private final int depth;
70 private final int applyFrom;
71 private final Collection<String> ignoredKeys;
72 private final Collection<String> unselectedKeys;
73
74 private OptionalDependencySelector(
75 int seed, int depth, int applyFrom, Collection<String> ignoredKeys, Collection<String> unselectedKeys) {
76 this.seed = seed;
77 this.depth = depth;
78 this.applyFrom = applyFrom;
79 this.ignoredKeys = ignoredKeys;
80 this.unselectedKeys = unselectedKeys;
81 }
82
83 @Override
84 public boolean selectDependency(Dependency dependency) {
85 requireNonNull(dependency, "dependency cannot be null");
86 String key = null;
87 if (ignoredKeys != null || unselectedKeys != null) {
88 key = ArtifactIdUtils.toId(dependency.getArtifact());
89 }
90 if (ignoredKeys != null) {
91 if (ignoredKeys.contains(key)) {
92 return true;
93 }
94 }
95 boolean result = depth < applyFrom || !dependency.isOptional();
96 if (!result && unselectedKeys != null) {
97 unselectedKeys.add(key);
98 }
99 return result;
100 }
101
102 @Override
103 @SuppressWarnings("unchecked")
104 public DependencySelector deriveChildSelector(DependencyCollectionContext context) {
105 requireNonNull(context, "context cannot be null");
106 if (depth >= applyFrom) {
107 return this;
108 }
109 return new OptionalDependencySelector(
110 seed,
111 depth + 1,
112 applyFrom,
113 (Collection<String>) context.getSession().getData().get(IGNORED_KEYS),
114 (Collection<String>) context.getSession().getData().get(UNSELECTED_KEYS));
115 }
116
117 @Override
118 public boolean equals(Object obj) {
119 if (this == obj) {
120 return true;
121 } else if (null == obj || !getClass().equals(obj.getClass())) {
122 return false;
123 }
124
125 OptionalDependencySelector that = (OptionalDependencySelector) obj;
126 return seed == that.seed && depth == that.depth && applyFrom == that.applyFrom;
127 }
128
129 @Override
130 public int hashCode() {
131 int hash = getClass().hashCode();
132 hash = hash * 31 + seed;
133 hash = hash * 31 + depth;
134 hash = hash * 31 + applyFrom;
135 return hash;
136 }
137
138 @Override
139 public String toString() {
140 return String.format("%s(applied: %s)", this.getClass().getSimpleName(), depth >= applyFrom);
141 }
142 }