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