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.artifact.ArtifactProperties;
30 import org.eclipse.aether.collection.DependencyCollectionContext;
31 import org.eclipse.aether.collection.DependencyManagement;
32 import org.eclipse.aether.collection.DependencyManager;
33 import org.eclipse.aether.graph.Dependency;
34 import org.eclipse.aether.graph.Exclusion;
35 import org.eclipse.aether.util.artifact.DependencyScopes;
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 private final int hashCode;
63
64
65
66
67 protected AbstractDependencyManager(int deriveUntil, int applyFrom) {
68 this(
69 0,
70 deriveUntil,
71 applyFrom,
72 Collections.emptyMap(),
73 Collections.emptyMap(),
74 Collections.emptyMap(),
75 Collections.emptyMap(),
76 Collections.emptyMap());
77 }
78
79 @SuppressWarnings("checkstyle:ParameterNumber")
80 protected AbstractDependencyManager(
81 int depth,
82 int deriveUntil,
83 int applyFrom,
84 Map<Object, String> managedVersions,
85 Map<Object, String> managedScopes,
86 Map<Object, Boolean> managedOptionals,
87 Map<Object, String> managedLocalPaths,
88 Map<Object, Collection<Exclusion>> managedExclusions) {
89 this.depth = depth;
90 this.deriveUntil = deriveUntil;
91 this.applyFrom = applyFrom;
92 this.managedVersions = managedVersions;
93 this.managedScopes = managedScopes;
94 this.managedOptionals = managedOptionals;
95 this.managedLocalPaths = managedLocalPaths;
96 this.managedExclusions = managedExclusions;
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 = managedDependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null);
158 if (localPath != null && !managedLocalPaths.containsKey(key)) {
159 if (managedLocalPaths == this.managedLocalPaths) {
160 managedLocalPaths = new HashMap<>(this.managedLocalPaths);
161 }
162 managedLocalPaths.put(key, localPath);
163 }
164
165 Collection<Exclusion> exclusions = managedDependency.getExclusions();
166 if (!exclusions.isEmpty()) {
167 if (managedExclusions == this.managedExclusions) {
168 managedExclusions = new HashMap<>(this.managedExclusions);
169 }
170 Collection<Exclusion> managed = managedExclusions.computeIfAbsent(key, k -> new LinkedHashSet<>());
171 managed.addAll(exclusions);
172 }
173 }
174
175 return newInstance(managedVersions, managedScopes, managedOptionals, managedLocalPaths, managedExclusions);
176 }
177
178 @Override
179 public DependencyManagement manageDependency(Dependency dependency) {
180 requireNonNull(dependency, "dependency cannot be null");
181 DependencyManagement management = null;
182 Object key = new Key(dependency.getArtifact());
183
184 if (depth >= applyFrom) {
185 String version = managedVersions.get(key);
186 if (version != null) {
187 management = new DependencyManagement();
188 management.setVersion(version);
189 }
190
191 String scope = managedScopes.get(key);
192 if (scope != null) {
193 if (management == null) {
194 management = new DependencyManagement();
195 }
196 management.setScope(scope);
197
198 if (!DependencyScopes.SYSTEM.equals(scope)
199 && dependency.getArtifact().getProperty(ArtifactProperties.LOCAL_PATH, null) != null) {
200 Map<String, String> properties =
201 new HashMap<>(dependency.getArtifact().getProperties());
202 properties.remove(ArtifactProperties.LOCAL_PATH);
203 management.setProperties(properties);
204 }
205 }
206
207 if ((DependencyScopes.SYSTEM.equals(scope))
208 || (scope == null && DependencyScopes.SYSTEM.equals(dependency.getScope()))) {
209 String localPath = managedLocalPaths.get(key);
210 if (localPath != null) {
211 if (management == null) {
212 management = new DependencyManagement();
213 }
214 Map<String, String> properties =
215 new HashMap<>(dependency.getArtifact().getProperties());
216 properties.put(ArtifactProperties.LOCAL_PATH, localPath);
217 management.setProperties(properties);
218 }
219 }
220
221 Boolean optional = managedOptionals.get(key);
222 if (optional != null) {
223 if (management == null) {
224 management = new DependencyManagement();
225 }
226 management.setOptional(optional);
227 }
228 }
229
230 Collection<Exclusion> exclusions = managedExclusions.get(key);
231 if (exclusions != null) {
232 if (management == null) {
233 management = new DependencyManagement();
234 }
235 Collection<Exclusion> result = new LinkedHashSet<>(dependency.getExclusions());
236 result.addAll(exclusions);
237 management.setExclusions(result);
238 }
239
240 return management;
241 }
242
243 @Override
244 public boolean equals(Object obj) {
245 if (this == obj) {
246 return true;
247 } else if (null == obj || !getClass().equals(obj.getClass())) {
248 return false;
249 }
250
251 AbstractDependencyManager that = (AbstractDependencyManager) obj;
252 return depth == that.depth
253 && deriveUntil == that.deriveUntil
254 && applyFrom == that.applyFrom
255 && managedVersions.equals(that.managedVersions)
256 && managedScopes.equals(that.managedScopes)
257 && managedOptionals.equals(that.managedOptionals)
258 && managedExclusions.equals(that.managedExclusions);
259 }
260
261 @Override
262 public int hashCode() {
263 return hashCode;
264 }
265
266 protected static class Key {
267
268 private final Artifact artifact;
269
270 private final int hashCode;
271
272 Key(Artifact artifact) {
273 this.artifact = artifact;
274 this.hashCode = Objects.hash(artifact.getGroupId(), artifact.getArtifactId());
275 }
276
277 @Override
278 public boolean equals(Object obj) {
279 if (obj == this) {
280 return true;
281 } else if (!(obj instanceof Key)) {
282 return false;
283 }
284 Key that = (Key) obj;
285 return artifact.getArtifactId().equals(that.artifact.getArtifactId())
286 && artifact.getGroupId().equals(that.artifact.getGroupId())
287 && artifact.getExtension().equals(that.artifact.getExtension())
288 && artifact.getClassifier().equals(that.artifact.getClassifier());
289 }
290
291 @Override
292 public int hashCode() {
293 return hashCode;
294 }
295 }
296 }