1 package org.apache.maven.plugin.war.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.artifact.Artifact;
23 import org.apache.maven.model.Dependency;
24 import org.codehaus.plexus.util.StringUtils;
25
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Set;
34
35
36
37
38
39
40
41
42
43
44
45
46 public class WebappStructure
47 {
48
49 private Map registeredFiles;
50
51 private List dependenciesInfo;
52
53 private transient PathSet allFiles = new PathSet();
54
55 private transient WebappStructure cache;
56
57
58
59
60
61
62 public WebappStructure( List dependencies )
63 {
64 this.dependenciesInfo = createDependenciesInfoList( dependencies );
65 this.registeredFiles = new HashMap();
66 this.cache = null;
67
68 }
69
70
71
72
73
74
75
76 public WebappStructure( List dependencies, WebappStructure cache )
77 {
78 this.dependenciesInfo = createDependenciesInfoList( dependencies );
79 this.registeredFiles = new HashMap();
80 if ( cache == null )
81 {
82 this.cache = new WebappStructure( dependencies );
83
84 }
85 else
86 {
87 this.cache = cache;
88 }
89 }
90
91
92
93
94
95
96 public List getDependenciesInfo()
97 {
98 return dependenciesInfo;
99 }
100
101
102
103
104
105
106 public List getDependencies()
107 {
108 final List result = new ArrayList();
109 if ( dependenciesInfo == null )
110 {
111 return result;
112 }
113 final Iterator it = dependenciesInfo.iterator();
114 while ( it.hasNext() )
115 {
116 DependencyInfo dependencyInfo = (DependencyInfo) it.next();
117 result.add( dependencyInfo.getDependency() );
118 }
119 return result;
120 }
121
122
123
124
125
126
127
128
129 public boolean isRegistered( String path )
130 {
131 return getFullStructure().contains( path );
132
133 }
134
135
136
137
138
139
140
141
142
143 public boolean registerFile( String id, String path )
144 {
145 if ( !isRegistered( path ) )
146 {
147 doRegister( id, path );
148 return true;
149 }
150 else
151 {
152 return false;
153 }
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 public boolean registerFileForced( String id, String path )
171 {
172 if ( !isRegistered( path ) )
173 {
174 doRegister( id, path );
175 return false;
176 }
177 else
178 {
179
180 getStructure( getOwner( path ) ).remove( path );
181 getStructure( id ).add( path );
182 return true;
183 }
184
185 }
186
187
188
189
190
191
192
193
194
195
196 public void registerFile( String id, String path, RegistrationCallback callback )
197 throws IOException
198 {
199
200
201 if ( isRegistered( path ) )
202 {
203 callback.refused( id, path, getOwner( path ) );
204 }
205 else
206 {
207 doRegister( id, path );
208
209 if ( cache.getOwner( path ) == null )
210 {
211 callback.registered( id, path );
212
213 }
214 else if ( cache.getOwner( path ).equals( id ) )
215 {
216 callback.alreadyRegistered( id, path );
217 }
218 else if ( getOwners().contains( cache.getOwner( path ) ) )
219 {
220 callback.superseded( id, path, cache.getOwner( path ) );
221 }
222 else
223 {
224 callback.supersededUnknownOwner( id, path, cache.getOwner( path ) );
225 }
226 }
227 }
228
229
230
231
232
233
234
235
236 public String getOwner( String path )
237 {
238 if ( !isRegistered( path ) )
239 {
240 return null;
241 }
242 else
243 {
244 final Iterator it = registeredFiles.keySet().iterator();
245 while ( it.hasNext() )
246 {
247 final String owner = (String) it.next();
248 final PathSet structure = getStructure( owner );
249 if ( structure.contains( path ) )
250 {
251 return owner;
252 }
253
254 }
255 throw new IllegalStateException(
256 "Should not happen, path [" + path + "] is flagged as being registered but was not found." );
257 }
258
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272 public Set getOwners()
273 {
274 return registeredFiles.keySet();
275 }
276
277
278
279
280
281
282 public PathSet getFullStructure()
283 {
284 return allFiles;
285 }
286
287
288
289
290
291
292
293 public PathSet getStructure( String id )
294 {
295 PathSet pathSet = (PathSet) registeredFiles.get( id );
296 if ( pathSet == null )
297 {
298 pathSet = new PathSet();
299 registeredFiles.put( id, pathSet );
300 }
301 return pathSet;
302 }
303
304
305
306
307
308
309
310 public void analyseDependencies( DependenciesAnalysisCallback callback )
311 {
312 if ( callback == null )
313 {
314 throw new NullPointerException( "Callback could not be null." );
315 }
316 if ( cache == null )
317 {
318
319 return;
320 }
321
322 final List currentDependencies = new ArrayList( getDependencies() );
323 final List previousDependencies = new ArrayList( cache.getDependencies() );
324 final Iterator it = currentDependencies.listIterator();
325 while ( it.hasNext() )
326 {
327 Dependency dependency = (Dependency) it.next();
328
329
330 final Dependency matchingDependency = matchDependency( previousDependencies, dependency );
331 if ( matchingDependency != null )
332 {
333 callback.unchangedDependency( dependency );
334
335 it.remove();
336 previousDependencies.remove( matchingDependency );
337 }
338 else
339 {
340
341 final Dependency previousDep = findDependency( dependency, previousDependencies );
342 if ( previousDep == null )
343 {
344 callback.newDependency( dependency );
345 it.remove();
346 }
347 else if ( !dependency.getVersion().equals( previousDep.getVersion() ) )
348 {
349 callback.updatedVersion( dependency, previousDep.getVersion() );
350 it.remove();
351 previousDependencies.remove( previousDep );
352 }
353 else if ( !dependency.getScope().equals( previousDep.getScope() ) )
354 {
355 callback.updatedScope( dependency, previousDep.getScope() );
356 it.remove();
357 previousDependencies.remove( previousDep );
358 }
359 else if ( dependency.isOptional() != previousDep.isOptional() )
360 {
361 callback.updatedOptionalFlag( dependency, previousDep.isOptional() );
362 it.remove();
363 previousDependencies.remove( previousDep );
364 }
365 else
366 {
367 callback.updatedUnknown( dependency, previousDep );
368 it.remove();
369 previousDependencies.remove( previousDep );
370 }
371 }
372 }
373 final Iterator previousDepIt = previousDependencies.iterator();
374 while ( previousDepIt.hasNext() )
375 {
376 Dependency dependency = (Dependency) previousDepIt.next();
377 callback.removedDependency( dependency );
378 }
379 }
380
381
382
383
384
385
386
387 public void registerTargetFileName( Artifact artifact, String targetFileName )
388 {
389 if ( dependenciesInfo != null )
390 {
391 final Iterator it = dependenciesInfo.iterator();
392 while ( it.hasNext() )
393 {
394 DependencyInfo dependencyInfo = (DependencyInfo) it.next();
395 if ( WarUtils.isRelated( artifact, dependencyInfo.getDependency() ) )
396 {
397 dependencyInfo.setTargetFileName( targetFileName );
398 }
399 }
400 }
401 }
402
403
404
405
406
407
408
409
410
411
412
413 public String getCachedTargetFileName( Dependency dependency )
414 {
415 if ( cache == null )
416 {
417 return null;
418 }
419 final Iterator it = cache.getDependenciesInfo().iterator();
420 while ( it.hasNext() )
421 {
422 DependencyInfo dependencyInfo = (DependencyInfo) it.next();
423 final Dependency dependency2 = dependencyInfo.getDependency();
424 if ( StringUtils.equals( dependency.getGroupId(), dependency2.getGroupId() )
425 && StringUtils.equals( dependency.getArtifactId(), dependency2.getArtifactId() )
426 && StringUtils.equals( dependency.getType(), dependency2.getType() )
427 && StringUtils.equals( dependency.getClassifier(), dependency2.getClassifier() ) )
428 {
429
430 return dependencyInfo.getTargetFileName();
431
432 }
433 }
434 return null;
435 }
436
437
438
439 private void doRegister( String id, String path )
440 {
441 getFullStructure().add( path );
442 getStructure( id ).add( path );
443 }
444
445
446
447
448
449
450
451
452 private Dependency findDependency( Dependency dependency, List dependencies )
453 {
454 final Iterator it = dependencies.iterator();
455 while ( it.hasNext() )
456 {
457 Dependency dep = (Dependency) it.next();
458 if ( dependency.getGroupId().equals( dep.getGroupId() )
459 && dependency.getArtifactId().equals( dep.getArtifactId() )
460 && dependency.getType().equals( dep.getType() )
461 && ( ( dependency.getClassifier() == null && dep.getClassifier() == null )
462 || ( dependency.getClassifier() != null
463 && dependency.getClassifier().equals( dep.getClassifier() ) ) ) )
464 {
465 return dep;
466 }
467 }
468 return null;
469 }
470
471 private Dependency matchDependency( List dependencies, Dependency dependency )
472 {
473 final Iterator it = dependencies.iterator();
474 while ( it.hasNext() )
475 {
476 Dependency dep = (Dependency) it.next();
477 if ( WarUtils.dependencyEquals( dep, dependency ) )
478 {
479 return dep;
480 }
481
482 }
483 return null;
484 }
485
486
487 private List createDependenciesInfoList( List dependencies )
488 {
489 if ( dependencies == null )
490 {
491 return Collections.EMPTY_LIST;
492 }
493 final List result = new ArrayList();
494 final Iterator it = dependencies.iterator();
495 while ( it.hasNext() )
496 {
497 Dependency dependency = (Dependency) it.next();
498 result.add( new DependencyInfo( dependency ) );
499 }
500 return result;
501 }
502
503
504 private Object readResolve()
505 {
506
507 this.allFiles = new PathSet();
508 final Iterator it = registeredFiles.values().iterator();
509 while ( it.hasNext() )
510 {
511 PathSet pathSet = (PathSet) it.next();
512 this.allFiles.addAll( pathSet );
513 }
514 return this;
515 }
516
517
518
519
520
521 public interface RegistrationCallback
522 {
523
524
525
526
527
528
529
530
531
532
533
534
535
536 void registered( String ownerId, String targetFilename )
537 throws IOException;
538
539
540
541
542
543
544
545
546
547
548
549
550 void alreadyRegistered( String ownerId, String targetFilename )
551 throws IOException;
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566 void refused( String ownerId, String targetFilename, String actualOwnerId )
567 throws IOException;
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583 void superseded( String ownerId, String targetFilename, String deprecatedOwnerId )
584 throws IOException;
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600 void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId )
601 throws IOException;
602 }
603
604
605
606
607 public interface DependenciesAnalysisCallback
608 {
609
610
611
612
613
614
615 void unchangedDependency( Dependency dependency );
616
617
618
619
620
621
622 void newDependency( Dependency dependency );
623
624
625
626
627
628
629 void removedDependency( Dependency dependency );
630
631
632
633
634
635
636
637 void updatedVersion( Dependency dependency, String previousVersion );
638
639
640
641
642
643
644
645 void updatedScope( Dependency dependency, String previousScope );
646
647
648
649
650
651
652
653
654 void updatedOptionalFlag( Dependency dependency, boolean previousOptional );
655
656
657
658
659
660
661
662 void updatedUnknown( Dependency dependency, Dependency previousDep );
663
664 }
665 }