1   package org.apache.maven.shared.dependency.tree;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.IdentityHashMap;
27  import java.util.Iterator;
28  import java.util.Map;
29  import java.util.Stack;
30  
31  import org.apache.maven.artifact.Artifact;
32  import org.apache.maven.artifact.resolver.ResolutionListener;
33  import org.apache.maven.artifact.resolver.ResolutionListenerForDepMgmt;
34  import org.apache.maven.artifact.versioning.VersionRange;
35  import org.apache.maven.shared.dependency.tree.traversal.CollectingDependencyNodeVisitor;
36  import org.codehaus.plexus.logging.Logger;
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  public class DependencyTreeResolutionListener implements ResolutionListener, ResolutionListenerForDepMgmt
47  {
48      
49  
50      
51  
52  
53      private final Logger logger;
54  
55      
56  
57  
58      private final Stack parentNodes;
59  
60      
61  
62  
63      private final Map nodesByArtifact;
64  
65      
66  
67  
68      private DependencyNode rootNode;
69  
70      
71  
72  
73      private DependencyNode currentNode;
74  
75      
76  
77  
78      private Map managedVersions = new HashMap();
79  
80      
81  
82  
83      private Map managedScopes = new HashMap();
84  
85  
86      
87  
88      
89  
90  
91  
92  
93  
94      public DependencyTreeResolutionListener( Logger logger )
95      {
96          this.logger = logger;
97  
98          parentNodes = new Stack();
99          nodesByArtifact = new IdentityHashMap();
100         rootNode = null;
101         currentNode = null;
102     }
103 
104 
105     
106 
107     
108 
109 
110     public void testArtifact( Artifact artifact )
111     {
112         log( "testArtifact: artifact=" + artifact );
113     }
114 
115 
116     
117 
118 
119     public void startProcessChildren( Artifact artifact )
120     {
121         log( "startProcessChildren: artifact=" + artifact );
122 
123         if ( !currentNode.getArtifact().equals( artifact ) )
124         {
125             throw new IllegalStateException( "Artifact was expected to be " + currentNode.getArtifact() + " but was "
126                 + artifact );
127         }
128 
129         parentNodes.push( currentNode );
130     }
131 
132 
133     
134 
135 
136     public void endProcessChildren( Artifact artifact )
137     {
138         DependencyNode node = ( DependencyNode ) parentNodes.pop();
139 
140         log( "endProcessChildren: artifact=" + artifact );
141 
142         if ( node == null )
143         {
144             throw new IllegalStateException( "Parent dependency node was null" );
145         }
146 
147         if ( !node.getArtifact().equals( artifact ) )
148         {
149             throw new IllegalStateException( "Parent dependency node artifact was expected to be " + node.getArtifact()
150                 + " but was " + artifact );
151         }
152     }
153 
154 
155     
156 
157 
158     public void includeArtifact( Artifact artifact )
159     {
160         log( "includeArtifact: artifact=" + artifact );
161 
162         DependencyNode existingNode = getNode( artifact );
163 
164         
165 
166 
167 
168         if ( existingNode == null && isCurrentNodeIncluded() )
169         {
170             DependencyNode node = addNode( artifact );
171 
172             
173 
174 
175 
176             flushDependencyManagement( node );
177         }
178     }
179 
180 
181     
182 
183 
184     public void omitForNearer( Artifact omitted, Artifact kept )
185     {
186         log( "omitForNearer: omitted=" + omitted + " kept=" + kept );
187 
188         if ( !omitted.getDependencyConflictId().equals( kept.getDependencyConflictId() ) )
189         {
190             throw new IllegalArgumentException( "Omitted artifact dependency conflict id "
191                 + omitted.getDependencyConflictId() + " differs from kept artifact dependency conflict id "
192                 + kept.getDependencyConflictId() );
193         }
194 
195         if ( isCurrentNodeIncluded() )
196         {
197             DependencyNode omittedNode = getNode( omitted );
198 
199             if ( omittedNode != null )
200             {
201                 removeNode( omitted );
202             }
203             else
204             {
205                 omittedNode = createNode( omitted );
206 
207                 currentNode = omittedNode;
208             }
209 
210             omittedNode.omitForConflict( kept );
211 
212             
213 
214 
215 
216             flushDependencyManagement( omittedNode );
217 
218             DependencyNode keptNode = getNode( kept );
219 
220             if ( keptNode == null )
221             {
222                 addNode( kept );
223             }
224         }
225     }
226 
227 
228     
229 
230 
231     public void updateScope( Artifact artifact, String scope )
232     {
233         log( "updateScope: artifact=" + artifact + ", scope=" + scope );
234 
235         DependencyNode node = getNode( artifact );
236 
237         if ( node == null )
238         {
239             
240             node = addNode( artifact );
241         }
242 
243         node.setOriginalScope( artifact.getScope() );
244     }
245 
246 
247     
248 
249 
250     public void manageArtifact( Artifact artifact, Artifact replacement )
251     {
252         
253 
254         log( "manageArtifact: artifact=" + artifact + ", replacement=" + replacement );
255 
256         if ( replacement.getVersion() != null )
257         {
258             manageArtifactVersion( artifact, replacement );
259         }
260 
261         if ( replacement.getScope() != null )
262         {
263             manageArtifactScope( artifact, replacement );
264         }
265     }
266 
267 
268     
269 
270 
271     public void omitForCycle( Artifact artifact )
272     {
273         log( "omitForCycle: artifact=" + artifact );
274 
275         if ( isCurrentNodeIncluded() )
276         {
277             DependencyNode node = createNode( artifact );
278 
279             node.omitForCycle();
280         }
281     }
282 
283 
284     
285 
286 
287     public void updateScopeCurrentPom( Artifact artifact, String scopeIgnored )
288     {
289         log( "updateScopeCurrentPom: artifact=" + artifact + ", scopeIgnored=" + scopeIgnored );
290 
291         DependencyNode node = getNode( artifact );
292 
293         if ( node == null )
294         {
295             
296             node = addNode( artifact );
297             
298         }
299 
300         node.setFailedUpdateScope( scopeIgnored );
301     }
302 
303 
304     
305 
306 
307     public void selectVersionFromRange( Artifact artifact )
308     {
309         log( "selectVersionFromRange: artifact=" + artifact );
310 
311         DependencyNode node = getNode( artifact );
312 
313         
314 
315 
316         if ( node == null && isCurrentNodeIncluded() )
317         {
318             node = addNode( artifact );
319         }
320 
321         node.setVersionSelectedFromRange( artifact.getVersionRange() );
322         node.setAvailableVersions( artifact.getAvailableVersions() );
323     }
324 
325 
326     
327 
328 
329     public void restrictRange( Artifact artifact, Artifact replacement, VersionRange versionRange )
330     {
331         log( "restrictRange: artifact=" + artifact + ", replacement=" + replacement + ", versionRange=" + versionRange );
332 
333         
334     }
335 
336 
337     
338 
339     
340 
341 
342     public void manageArtifactVersion( Artifact artifact, Artifact replacement )
343     {
344         log( "manageArtifactVersion: artifact=" + artifact + ", replacement=" + replacement );
345 
346         
347 
348 
349 
350         if ( isCurrentNodeIncluded() && !replacement.getVersion().equals( artifact.getVersion() ) )
351         {
352             
353 
354 
355 
356             managedVersions.put( getRangeId( replacement ), artifact.getVersion() );
357         }
358     }
359 
360 
361     
362 
363 
364     public void manageArtifactScope( Artifact artifact, Artifact replacement )
365     {
366         log( "manageArtifactScope: artifact=" + artifact + ", replacement=" + replacement );
367 
368         
369 
370 
371 
372         if ( isCurrentNodeIncluded() && !replacement.getScope().equals( artifact.getScope() ) )
373         {
374             
375 
376 
377 
378             managedScopes.put( getRangeId( replacement ), artifact.getScope() );
379         }
380     }
381 
382 
383     
384 
385     
386 
387 
388 
389 
390 
391     public Collection getNodes()
392     {
393         return Collections.unmodifiableCollection( nodesByArtifact.values() );
394     }
395 
396 
397     
398 
399 
400 
401 
402     public DependencyNode getRootNode()
403     {
404         return rootNode;
405     }
406 
407 
408     
409 
410     
411 
412 
413 
414 
415 
416     private void log( String message )
417     {
418         int depth = parentNodes.size();
419 
420         StringBuffer buffer = new StringBuffer();
421 
422         for ( int i = 0; i < depth; i++ )
423         {
424             buffer.append( "  " );
425         }
426 
427         buffer.append( message );
428 
429         logger.debug( buffer.toString() );
430     }
431 
432 
433     
434 
435 
436 
437 
438 
439 
440     private DependencyNode createNode( Artifact artifact )
441     {
442         DependencyNode node = new DependencyNode( artifact );
443 
444         if ( !parentNodes.isEmpty() )
445         {
446             DependencyNode parent = ( DependencyNode ) parentNodes.peek();
447 
448             parent.addChild( node );
449         }
450 
451         return node;
452     }
453 
454 
455     
456 
457 
458 
459 
460 
461 
462 
463     
464     DependencyNode addNode( Artifact artifact )
465     {
466         DependencyNode node = createNode( artifact );
467 
468         DependencyNode previousNode = ( DependencyNode ) nodesByArtifact.put( node.getArtifact(), node );
469 
470         if ( previousNode != null )
471         {
472             throw new IllegalStateException( "Duplicate node registered for artifact: " + node.getArtifact() );
473         }
474 
475         if ( rootNode == null )
476         {
477             rootNode = node;
478         }
479 
480         currentNode = node;
481 
482         return node;
483     }
484 
485 
486     
487 
488 
489 
490 
491 
492 
493 
494     private DependencyNode getNode( Artifact artifact )
495     {
496         return ( DependencyNode ) nodesByArtifact.get( artifact );
497     }
498 
499 
500     
501 
502 
503 
504 
505 
506     private void removeNode( Artifact artifact )
507     {
508         DependencyNode node = ( DependencyNode ) nodesByArtifact.remove( artifact );
509 
510         if ( !artifact.equals( node.getArtifact() ) )
511         {
512             throw new IllegalStateException( "Removed dependency node artifact was expected to be " + artifact
513                 + " but was " + node.getArtifact() );
514         }
515     }
516 
517 
518     
519 
520 
521 
522 
523 
524 
525     private boolean isCurrentNodeIncluded()
526     {
527         boolean included = true;
528 
529         for ( Iterator iterator = parentNodes.iterator(); included && iterator.hasNext(); )
530         {
531             DependencyNode node = ( DependencyNode ) iterator.next();
532 
533             if ( node.getState() != DependencyNode.INCLUDED )
534             {
535                 included = false;
536             }
537         }
538 
539         return included;
540     }
541 
542 
543     
544 
545 
546 
547 
548 
549 
550     private void flushDependencyManagement( DependencyNode node )
551     {
552         Artifact artifact = node.getArtifact();
553         String premanagedVersion = ( String ) managedVersions.get( getRangeId( artifact ) );
554         String premanagedScope = ( String ) managedScopes.get( getRangeId( artifact ) );
555 
556         if ( premanagedVersion != null || premanagedScope != null )
557         {
558             if ( premanagedVersion != null )
559             {
560                 node.setPremanagedVersion( premanagedVersion );
561             }
562 
563             if ( premanagedScope != null )
564             {
565                 node.setPremanagedScope( premanagedScope );
566             }
567 
568             premanagedVersion = null;
569             premanagedScope = null;
570         }
571     }
572 
573 
574     private static String getRangeId( Artifact artifact )
575     {
576         return artifact.getDependencyConflictId() + ":" + artifact.getVersionRange();
577     }
578 
579 
580     public void manageArtifactSystemPath( Artifact artifact, Artifact replacement )
581     {
582         
583     }
584 }