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