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 final Iterator it = dependenciesInfo.iterator();
390 while ( it.hasNext() )
391 {
392 DependencyInfo dependencyInfo = (DependencyInfo) it.next();
393 if ( WarUtils.isRelated( artifact, dependencyInfo.getDependency() ) )
394 {
395 dependencyInfo.setTargetFileName( targetFileName );
396 }
397 }
398 }
399
400
401
402
403
404
405
406
407
408
409
410 public String getCachedTargetFileName( Dependency dependency )
411 {
412 if ( cache == null )
413 {
414 return null;
415 }
416 final Iterator it = cache.getDependenciesInfo().iterator();
417 while ( it.hasNext() )
418 {
419 DependencyInfo dependencyInfo = (DependencyInfo) it.next();
420 final Dependency dependency2 = dependencyInfo.getDependency();
421 if ( StringUtils.equals( dependency.getGroupId(), dependency2.getGroupId() )
422 && StringUtils.equals( dependency.getArtifactId(), dependency2.getArtifactId() )
423 && StringUtils.equals( dependency.getType(), dependency2.getType() )
424 && StringUtils.equals( dependency.getClassifier(), dependency2.getClassifier() ) )
425 {
426
427 return dependencyInfo.getTargetFileName();
428
429 }
430 }
431 return null;
432 }
433
434
435
436 private void doRegister( String id, String path )
437 {
438 getFullStructure().add( path );
439 getStructure( id ).add( path );
440 }
441
442
443
444
445
446
447
448
449 private Dependency findDependency( Dependency dependency, List dependencies )
450 {
451 final Iterator it = dependencies.iterator();
452 while ( it.hasNext() )
453 {
454 Dependency dep = (Dependency) it.next();
455 if ( dependency.getGroupId().equals( dep.getGroupId() )
456 && dependency.getArtifactId().equals( dep.getArtifactId() )
457 && dependency.getType().equals( dep.getType() )
458 && ( ( dependency.getClassifier() == null && dep.getClassifier() == null )
459 || ( dependency.getClassifier() != null
460 && dependency.getClassifier().equals( dep.getClassifier() ) ) ) )
461 {
462 return dep;
463 }
464 }
465 return null;
466 }
467
468 private Dependency matchDependency( List dependencies, Dependency dependency )
469 {
470 final Iterator it = dependencies.iterator();
471 while ( it.hasNext() )
472 {
473 Dependency dep = (Dependency) it.next();
474 if ( WarUtils.dependencyEquals( dep, dependency ) )
475 {
476 return dep;
477 }
478
479 }
480 return null;
481 }
482
483
484 private List createDependenciesInfoList( List dependencies )
485 {
486 if ( dependencies == null )
487 {
488 return Collections.EMPTY_LIST;
489 }
490 final List result = new ArrayList();
491 final Iterator it = dependencies.iterator();
492 while ( it.hasNext() )
493 {
494 Dependency dependency = (Dependency) it.next();
495 result.add( new DependencyInfo( dependency ) );
496 }
497 return result;
498 }
499
500
501 private Object readResolve()
502 {
503
504 this.allFiles = new PathSet();
505 final Iterator it = registeredFiles.values().iterator();
506 while ( it.hasNext() )
507 {
508 PathSet pathSet = (PathSet) it.next();
509 this.allFiles.addAll( pathSet );
510 }
511 return this;
512 }
513
514
515
516
517
518 public interface RegistrationCallback
519 {
520
521
522
523
524
525
526
527
528
529
530
531
532
533 void registered( String ownerId, String targetFilename )
534 throws IOException;
535
536
537
538
539
540
541
542
543
544
545
546
547 void alreadyRegistered( String ownerId, String targetFilename )
548 throws IOException;
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563 void refused( String ownerId, String targetFilename, String actualOwnerId )
564 throws IOException;
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580 void superseded( String ownerId, String targetFilename, String deprecatedOwnerId )
581 throws IOException;
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597 void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId )
598 throws IOException;
599 }
600
601
602
603
604 public interface DependenciesAnalysisCallback
605 {
606
607
608
609
610
611
612 void unchangedDependency( Dependency dependency );
613
614
615
616
617
618
619 void newDependency( Dependency dependency );
620
621
622
623
624
625
626 void removedDependency( Dependency dependency );
627
628
629
630
631
632
633
634 void updatedVersion( Dependency dependency, String previousVersion );
635
636
637
638
639
640
641
642 void updatedScope( Dependency dependency, String previousScope );
643
644
645
646
647
648
649
650
651 void updatedOptionalFlag( Dependency dependency, boolean previousOptional );
652
653
654
655
656
657
658
659 void updatedUnknown( Dependency dependency, Dependency previousDep );
660
661 }
662 }