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.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.LinkedHashSet;
25 import java.util.Map;
26 import java.util.Objects;
27
28 import org.eclipse.aether.artifact.Artifact;
29 import org.eclipse.aether.collection.DependencyCollectionContext;
30 import org.eclipse.aether.collection.DependencyManagement;
31 import org.eclipse.aether.collection.DependencyManager;
32 import org.eclipse.aether.graph.Dependency;
33 import org.eclipse.aether.graph.Exclusion;
34 import org.eclipse.aether.scope.ScopeManager;
35 import org.eclipse.aether.scope.SystemDependencyScope;
36
37 import static java.util.Objects.requireNonNull;
38
39
40
41
42
43
44 public abstract class AbstractDependencyManager implements DependencyManager {
45
46 protected final int depth;
47
48 protected final int deriveUntil;
49
50 protected final int applyFrom;
51
52 protected final Map<Object, String> managedVersions;
53
54 protected final Map<Object, String> managedScopes;
55
56 protected final Map<Object, Boolean> managedOptionals;
57
58 protected final Map<Object, String> managedLocalPaths;
59
60 protected final Map<Object, Collection<Exclusion>> managedExclusions;
61
62 protected final SystemDependencyScope systemDependencyScope;
63
64 private final int hashCode;
65
66 protected AbstractDependencyManager(int deriveUntil, int applyFrom, ScopeManager scopeManager) {
67 this(
68 0,
69 deriveUntil,
70 applyFrom,
71 Collections.emptyMap(),
72 Collections.emptyMap(),
73 Collections.emptyMap(),
74 Collections.emptyMap(),
75 Collections.emptyMap(),
76 scopeManager != null
77 ? scopeManager.getSystemDependencyScope().orElse(null)
78 : SystemDependencyScope.LEGACY);
79 }
80
81 @SuppressWarnings("checkstyle:ParameterNumber")
82 protected AbstractDependencyManager(
83 int depth,
84 int deriveUntil,
85 int applyFrom,
86 Map<Object, String> managedVersions,
87 Map<Object, String> managedScopes,
88 Map<Object, Boolean> managedOptionals,
89 Map<Object, String> managedLocalPaths,
90 Map<Object, Collection<Exclusion>> managedExclusions,
91 SystemDependencyScope systemDependencyScope) {
92 this.depth = depth;
93 this.deriveUntil = deriveUntil;
94 this.applyFrom = applyFrom;
95 this.managedVersions = requireNonNull(managedVersions);
96 this.managedScopes = requireNonNull(managedScopes);
97 this.managedOptionals = requireNonNull(managedOptionals);
98 this.managedLocalPaths = requireNonNull(managedLocalPaths);
99 this.managedExclusions = requireNonNull(managedExclusions);
100
101 this.systemDependencyScope = systemDependencyScope;
102
103 this.hashCode = Objects.hash(
104 depth,
105 deriveUntil,
106 applyFrom,
107 managedVersions,
108 managedScopes,
109 managedOptionals,
110 managedLocalPaths,
111 managedExclusions);
112 }
113
114 protected abstract DependencyManager newInstance(
115 Map<Object, String> managedVersions,
116 Map<Object, String> managedScopes,
117 Map<Object, Boolean> managedOptionals,
118 Map<Object, String> managedLocalPaths,
119 Map<Object, Collection<Exclusion>> managedExclusions);
120
121 @Override
122 public DependencyManager deriveChildManager(DependencyCollectionContext context) {
123 requireNonNull(context, "context cannot be null");
124 if (depth >= deriveUntil) {
125 return this;
126 }
127
128 Map<Object, String> managedVersions = this.managedVersions;
129 Map<Object, String> managedScopes = this.managedScopes;
130 Map<Object, Boolean> managedOptionals = this.managedOptionals;
131 Map<Object, String> managedLocalPaths = this.managedLocalPaths;
132 Map<Object, Collection<Exclusion>> managedExclusions = this.managedExclusions;
133
134 for (Dependency managedDependency : context.getManagedDependencies()) {
135 Artifact artifact = managedDependency.getArtifact();
136 Object key = new Key(artifact);
137
138 String version = artifact.getVersion();
139 if (!version.isEmpty() && !managedVersions.containsKey(key)) {
140 if (managedVersions == this.managedVersions) {
141 managedVersions = new HashMap<>(this.managedVersions);
142 }
143 managedVersions.put(key, version);
144 }
145
146 String scope = managedDependency.getScope();
147 if (!scope.isEmpty() && !managedScopes.containsKey(key)) {
148 if (managedScopes == this.managedScopes) {
149 managedScopes = new HashMap<>(this.managedScopes);
150 }
151 managedScopes.put(key, scope);
152 }
153
154 Boolean optional = managedDependency.getOptional();
155 if (optional != null && !managedOptionals.containsKey(key)) {
156 if (managedOptionals == this.managedOptionals) {
157 managedOptionals = new HashMap<>(this.managedOptionals);
158 }
159 managedOptionals.put(key, optional);
160 }
161
162 String localPath = systemDependencyScope == null
163 ? null
164 : systemDependencyScope.getSystemPath(managedDependency.getArtifact());
165 if (localPath != null && !managedLocalPaths.containsKey(key)) {
166 if (managedLocalPaths == this.managedLocalPaths) {
167 managedLocalPaths = new HashMap<>(this.managedLocalPaths);
168 }
169 managedLocalPaths.put(key, localPath);
170 }
171
172 Collection<Exclusion> exclusions = managedDependency.getExclusions();
173 if (!exclusions.isEmpty()) {
174 if (managedExclusions == this.managedExclusions) {
175 managedExclusions = new HashMap<>(this.managedExclusions);
176 }
177 Collection<Exclusion> managed = managedExclusions.computeIfAbsent(key, k -> new LinkedHashSet<>());
178 managed.addAll(exclusions);
179 }
180 }
181
182 return newInstance(managedVersions, managedScopes, managedOptionals, managedLocalPaths, managedExclusions);
183 }
184
185 @Override
186 public DependencyManagement manageDependency(Dependency dependency) {
187 requireNonNull(dependency, "dependency cannot be null");
188 DependencyManagement management = null;
189 Object key = new Key(dependency.getArtifact());
190
191 if (depth >= applyFrom) {
192 String version = managedVersions.get(key);
193 if (version != null) {
194 management = new DependencyManagement();
195 management.setVersion(version);
196 }
197
198 String scope = managedScopes.get(key);
199 if (scope != null) {
200 if (management == null) {
201 management = new DependencyManagement();
202 }
203 management.setScope(scope);
204
205 if (systemDependencyScope != null
206 && !systemDependencyScope.is(scope)
207 && systemDependencyScope.getSystemPath(dependency.getArtifact()) != null) {
208 Map<String, String> properties =
209 new HashMap<>(dependency.getArtifact().getProperties());
210 systemDependencyScope.setSystemPath(properties, null);
211 management.setProperties(properties);
212 }
213 }
214
215 if (systemDependencyScope != null
216 && (systemDependencyScope.is(scope)
217 || (scope == null && systemDependencyScope.is(dependency.getScope())))) {
218 String localPath = managedLocalPaths.get(key);
219 if (localPath != null) {
220 if (management == null) {
221 management = new DependencyManagement();
222 }
223 Map<String, String> properties =
224 new HashMap<>(dependency.getArtifact().getProperties());
225 systemDependencyScope.setSystemPath(properties, localPath);
226 management.setProperties(properties);
227 }
228 }
229
230 Boolean optional = managedOptionals.get(key);
231 if (optional != null) {
232 if (management == null) {
233 management = new DependencyManagement();
234 }
235 management.setOptional(optional);
236 }
237 }
238
239 Collection<Exclusion> exclusions = managedExclusions.get(key);
240 if (exclusions != null) {
241 if (management == null) {
242 management = new DependencyManagement();
243 }
244 Collection<Exclusion> result = new LinkedHashSet<>(dependency.getExclusions());
245 result.addAll(exclusions);
246 management.setExclusions(result);
247 }
248
249 return management;
250 }
251
252 @Override
253 public boolean equals(Object obj) {
254 if (this == obj) {
255 return true;
256 } else if (null == obj || !getClass().equals(obj.getClass())) {
257 return false;
258 }
259
260 AbstractDependencyManager that = (AbstractDependencyManager) obj;
261 return depth == that.depth
262 && deriveUntil == that.deriveUntil
263 && applyFrom == that.applyFrom
264 && managedVersions.equals(that.managedVersions)
265 && managedScopes.equals(that.managedScopes)
266 && managedOptionals.equals(that.managedOptionals)
267 && managedExclusions.equals(that.managedExclusions);
268 }
269
270 @Override
271 public int hashCode() {
272 return hashCode;
273 }
274
275 protected static class Key {
276
277 private final Artifact artifact;
278
279 private final int hashCode;
280
281 Key(Artifact artifact) {
282 this.artifact = artifact;
283 this.hashCode = Objects.hash(artifact.getGroupId(), artifact.getArtifactId());
284 }
285
286 @Override
287 public boolean equals(Object obj) {
288 if (obj == this) {
289 return true;
290 } else if (!(obj instanceof Key)) {
291 return false;
292 }
293 Key that = (Key) obj;
294 return artifact.getArtifactId().equals(that.artifact.getArtifactId())
295 && artifact.getGroupId().equals(that.artifact.getGroupId())
296 && artifact.getExtension().equals(that.artifact.getExtension())
297 && artifact.getClassifier().equals(that.artifact.getClassifier());
298 }
299
300 @Override
301 public int hashCode() {
302 return hashCode;
303 }
304
305 @Override
306 public String toString() {
307 return String.valueOf(artifact);
308 }
309 }
310 }