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