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