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