View Javadoc
1   package org.eclipse.aether.util.graph.manager;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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  /**
38   * A dependency manager that mimics the way Maven 2.x works.
39   */
40  public final class ClassicDependencyManager
41      implements DependencyManager
42  {
43  
44      private final int depth;
45  
46      private final Map<Object, String> managedVersions;
47  
48      private final Map<Object, String> managedScopes;
49  
50      private final Map<Object, Boolean> managedOptionals;
51  
52      private final Map<Object, String> managedLocalPaths;
53  
54      private final Map<Object, Collection<Exclusion>> managedExclusions;
55  
56      private int hashCode;
57  
58      /**
59       * Creates a new dependency manager without any management information.
60       */
61      public ClassicDependencyManager()
62      {
63          this( 0, Collections.<Object, String>emptyMap(), Collections.<Object, String>emptyMap(),
64                Collections.<Object, Boolean>emptyMap(), Collections.<Object, String>emptyMap(),
65                Collections.<Object, Collection<Exclusion>>emptyMap() );
66      }
67  
68      private ClassicDependencyManager( int depth, Map<Object, String> managedVersions,
69                                        Map<Object, String> managedScopes, Map<Object, Boolean> managedOptionals,
70                                        Map<Object, String> managedLocalPaths,
71                                        Map<Object, Collection<Exclusion>> managedExclusions )
72      {
73          this.depth = depth;
74          this.managedVersions = managedVersions;
75          this.managedScopes = managedScopes;
76          this.managedOptionals = managedOptionals;
77          this.managedLocalPaths = managedLocalPaths;
78          this.managedExclusions = managedExclusions;
79      }
80  
81      public DependencyManager deriveChildManager( DependencyCollectionContext context )
82      {
83          if ( depth >= 2 )
84          {
85              return this;
86          }
87          else if ( depth == 1 )
88          {
89              return new ClassicDependencyManager( depth + 1, managedVersions, managedScopes, managedOptionals,
90                                                   managedLocalPaths, managedExclusions );
91          }
92  
93          Map<Object, String> managedVersions = this.managedVersions;
94          Map<Object, String> managedScopes = this.managedScopes;
95          Map<Object, Boolean> managedOptionals = this.managedOptionals;
96          Map<Object, String> managedLocalPaths = this.managedLocalPaths;
97          Map<Object, Collection<Exclusion>> managedExclusions = this.managedExclusions;
98  
99          for ( Dependency managedDependency : context.getManagedDependencies() )
100         {
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             {
107                 if ( managedVersions == this.managedVersions )
108                 {
109                     managedVersions = new HashMap<Object, String>( this.managedVersions );
110                 }
111                 managedVersions.put( key, version );
112             }
113 
114             String scope = managedDependency.getScope();
115             if ( scope.length() > 0 && !managedScopes.containsKey( key ) )
116             {
117                 if ( managedScopes == this.managedScopes )
118                 {
119                     managedScopes = new HashMap<Object, String>( this.managedScopes );
120                 }
121                 managedScopes.put( key, scope );
122             }
123 
124             Boolean optional = managedDependency.getOptional();
125             if ( optional != null && !managedOptionals.containsKey( key ) )
126             {
127                 if ( managedOptionals == this.managedOptionals )
128                 {
129                     managedOptionals = new HashMap<Object, Boolean>( this.managedOptionals );
130                 }
131                 managedOptionals.put( key, optional );
132             }
133 
134             String localPath = managedDependency.getArtifact().getProperty( ArtifactProperties.LOCAL_PATH, null );
135             if ( localPath != null && !managedLocalPaths.containsKey( key ) )
136             {
137                 if ( managedLocalPaths == this.managedLocalPaths )
138                 {
139                     managedLocalPaths = new HashMap<Object, String>( this.managedLocalPaths );
140                 }
141                 managedLocalPaths.put( key, localPath );
142             }
143 
144             Collection<Exclusion> exclusions = managedDependency.getExclusions();
145             if ( !exclusions.isEmpty() )
146             {
147                 if ( managedExclusions == this.managedExclusions )
148                 {
149                     managedExclusions = new HashMap<Object, Collection<Exclusion>>( this.managedExclusions );
150                 }
151                 Collection<Exclusion> managed = managedExclusions.get( key );
152                 if ( managed == null )
153                 {
154                     managed = new LinkedHashSet<Exclusion>();
155                     managedExclusions.put( key, managed );
156                 }
157                 managed.addAll( exclusions );
158             }
159         }
160 
161         return new ClassicDependencyManager( depth + 1, managedVersions, managedScopes, managedOptionals,
162                                              managedLocalPaths, managedExclusions );
163     }
164 
165     public DependencyManagement manageDependency( Dependency dependency )
166     {
167         DependencyManagement management = null;
168 
169         Object key = getKey( dependency.getArtifact() );
170 
171         if ( depth >= 2 )
172         {
173             String version = managedVersions.get( key );
174             if ( version != null )
175             {
176                 if ( management == null )
177                 {
178                     management = new DependencyManagement();
179                 }
180                 management.setVersion( version );
181             }
182 
183             String scope = managedScopes.get( key );
184             if ( scope != null )
185             {
186                 if ( management == null )
187                 {
188                     management = new DependencyManagement();
189                 }
190                 management.setScope( scope );
191 
192                 if ( !JavaScopes.SYSTEM.equals( scope )
193                     && dependency.getArtifact().getProperty( ArtifactProperties.LOCAL_PATH, null ) != null )
194                 {
195                     Map<String, String> properties =
196                         new HashMap<String, String>( dependency.getArtifact().getProperties() );
197                     properties.remove( ArtifactProperties.LOCAL_PATH );
198                     management.setProperties( properties );
199                 }
200             }
201 
202             if ( ( scope != null && JavaScopes.SYSTEM.equals( scope ) )
203                 || ( scope == null && JavaScopes.SYSTEM.equals( dependency.getScope() ) ) )
204             {
205                 String localPath = managedLocalPaths.get( key );
206                 if ( localPath != null )
207                 {
208                     if ( management == null )
209                     {
210                         management = new DependencyManagement();
211                     }
212                     Map<String, String> properties =
213                         new HashMap<String, String>( dependency.getArtifact().getProperties() );
214                     properties.put( ArtifactProperties.LOCAL_PATH, localPath );
215                     management.setProperties( properties );
216                 }
217             }
218 
219             Boolean optional = managedOptionals.get( key );
220             if ( optional != null )
221             {
222                 if ( management == null )
223                 {
224                     management = new DependencyManagement();
225                 }
226                 management.setOptional( optional );
227             }
228         }
229 
230         Collection<Exclusion> exclusions = managedExclusions.get( key );
231         if ( exclusions != null )
232         {
233             if ( management == null )
234             {
235                 management = new DependencyManagement();
236             }
237             Collection<Exclusion> result = new LinkedHashSet<Exclusion>( dependency.getExclusions() );
238             result.addAll( exclusions );
239             management.setExclusions( result );
240         }
241 
242         return management;
243     }
244 
245     private Object getKey( Artifact a )
246     {
247         return new Key( a );
248     }
249 
250     @Override
251     public boolean equals( Object obj )
252     {
253         if ( this == obj )
254         {
255             return true;
256         }
257         else if ( null == obj || !getClass().equals( obj.getClass() ) )
258         {
259             return false;
260         }
261 
262         ClassicDependencyManager that = (ClassicDependencyManager) obj;
263         return depth == that.depth && managedVersions.equals( that.managedVersions )
264             && managedScopes.equals( that.managedScopes ) && managedOptionals.equals( that.managedOptionals )
265             && managedExclusions.equals( that.managedExclusions );
266     }
267 
268     @Override
269     public int hashCode()
270     {
271         if ( hashCode == 0 )
272         {
273             int hash = 17;
274             hash = hash * 31 + depth;
275             hash = hash * 31 + managedVersions.hashCode();
276             hash = hash * 31 + managedScopes.hashCode();
277             hash = hash * 31 + managedOptionals.hashCode();
278             hash = hash * 31 + managedExclusions.hashCode();
279             hashCode = hash;
280         }
281         return hashCode;
282     }
283 
284     static class Key
285     {
286 
287         private final Artifact artifact;
288 
289         private final int hashCode;
290 
291         Key( Artifact artifact )
292         {
293             this.artifact = artifact;
294 
295             int hash = 17;
296             hash = hash * 31 + artifact.getGroupId().hashCode();
297             hash = hash * 31 + artifact.getArtifactId().hashCode();
298             hashCode = hash;
299         }
300 
301         @Override
302         public boolean equals( Object obj )
303         {
304             if ( obj == this )
305             {
306                 return true;
307             }
308             else if ( !( obj instanceof Key ) )
309             {
310                 return false;
311             }
312             Key that = (Key) obj;
313             return artifact.getArtifactId().equals( that.artifact.getArtifactId() )
314                 && artifact.getGroupId().equals( that.artifact.getGroupId() )
315                 && artifact.getExtension().equals( that.artifact.getExtension() )
316                 && artifact.getClassifier().equals( that.artifact.getClassifier() );
317         }
318 
319         @Override
320         public int hashCode()
321         {
322             return hashCode;
323         }
324 
325     }
326 
327 }