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 }