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