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