1 package org.apache.maven.plugin.war;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.Iterator;
28 import java.util.List;
29
30 import org.apache.maven.archiver.MavenArchiveConfiguration;
31 import org.apache.maven.artifact.factory.ArtifactFactory;
32 import org.apache.maven.execution.MavenSession;
33 import org.apache.maven.model.Resource;
34 import org.apache.maven.plugin.AbstractMojo;
35 import org.apache.maven.plugin.MojoExecutionException;
36 import org.apache.maven.plugin.MojoFailureException;
37 import org.apache.maven.plugin.logging.Log;
38 import org.apache.maven.plugin.war.overlay.OverlayManager;
39 import org.apache.maven.plugin.war.packaging.DependenciesAnalysisPackagingTask;
40 import org.apache.maven.plugin.war.packaging.OverlayPackagingTask;
41 import org.apache.maven.plugin.war.packaging.SaveWebappStructurePostPackagingTask;
42 import org.apache.maven.plugin.war.packaging.WarPackagingContext;
43 import org.apache.maven.plugin.war.packaging.WarPackagingTask;
44 import org.apache.maven.plugin.war.packaging.WarPostPackagingTask;
45 import org.apache.maven.plugin.war.packaging.WarProjectPackagingTask;
46 import org.apache.maven.plugin.war.util.WebappStructure;
47 import org.apache.maven.plugin.war.util.WebappStructureSerializer;
48 import org.apache.maven.project.MavenProject;
49 import org.apache.maven.shared.filtering.MavenFileFilter;
50 import org.apache.maven.shared.filtering.MavenFilteringException;
51 import org.apache.maven.shared.filtering.MavenResourcesExecution;
52 import org.apache.maven.shared.filtering.MavenResourcesFiltering;
53 import org.codehaus.plexus.archiver.jar.JarArchiver;
54 import org.codehaus.plexus.archiver.manager.ArchiverManager;
55 import org.codehaus.plexus.util.StringUtils;
56
57
58
59
60
61
62 public abstract class AbstractWarMojo
63 extends AbstractMojo
64 {
65 public static final String DEFAULT_FILE_NAME_MAPPING = "@{artifactId}@-@{version}@.@{extension}@";
66
67 public static final String DEFAULT_FILE_NAME_MAPPING_CLASSIFIER =
68 "@{artifactId}@-@{version}@-@{classifier}@.@{extension}@";
69
70 private static final String[] EMPTY_STRING_ARRAY = {};
71
72 private static final String META_INF = "META-INF";
73
74 private static final String WEB_INF = "WEB-INF";
75
76
77
78
79
80
81
82
83 private MavenProject project;
84
85
86
87
88
89
90
91
92 private File classesDirectory;
93
94
95
96
97
98
99
100
101
102 private boolean archiveClasses;
103
104
105
106
107
108
109
110 private JarArchiver jarArchiver;
111
112
113
114
115
116
117
118 private File webappDirectory;
119
120
121
122
123
124
125
126
127 private File warSourceDirectory;
128
129
130
131
132
133
134 private Resource[] webResources;
135
136
137
138
139
140
141 private List filters;
142
143
144
145
146
147
148 private File webXml;
149
150
151
152
153
154
155
156
157
158 private File containerConfigXML;
159
160
161
162
163
164
165
166 private File workDirectory;
167
168
169
170
171
172
173
174
175 private String outputFileNameMapping;
176
177
178
179
180
181
182
183
184 private File cacheFile;
185
186
187
188
189
190
191
192
193 private boolean useCache = false;
194
195
196
197
198
199
200 private ArtifactFactory artifactFactory;
201
202
203
204
205
206
207
208 private ArchiverManager archiverManager;
209
210
211
212
213
214 private MavenFileFilter mavenFileFilter;
215
216
217
218
219
220 private MavenResourcesFiltering mavenResourcesFiltering;
221
222
223
224
225
226
227
228 private String warSourceIncludes;
229
230
231
232
233
234
235
236 private String warSourceExcludes;
237
238
239
240
241
242
243
244
245
246 private String dependentWarIncludes = "**/**";
247
248
249
250
251
252
253
254
255 private String dependentWarExcludes = "META-INF/**";
256
257
258
259
260
261
262
263 private List overlays = new ArrayList();
264
265
266
267
268
269
270
271
272 private List nonFilteredFileExtensions;
273
274
275
276
277
278
279
280 private MavenSession session;
281
282
283
284
285
286
287
288 private boolean filteringDeploymentDescriptors = false;
289
290
291
292
293
294
295
296
297 private boolean escapedBackslashesInFilePath = false;
298
299
300
301
302
303
304
305
306 protected String escapeString;
307
308
309
310
311
312
313
314 private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
315
316 private final WebappStructureSerializer webappStructureSerialier = new WebappStructureSerializer();
317
318 private final Overlay currentProjectOverlay = Overlay.createInstance();
319
320
321 public Overlay getCurrentProjectOverlay()
322 {
323 return currentProjectOverlay;
324 }
325
326
327
328
329
330
331
332 protected String[] getExcludes()
333 {
334 List excludeList = new ArrayList();
335 if ( StringUtils.isNotEmpty( warSourceExcludes ) )
336 {
337 excludeList.addAll( Arrays.asList( StringUtils.split( warSourceExcludes, "," ) ) );
338 }
339
340
341 if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
342 {
343 excludeList.add( "**/" + WEB_INF + "/web.xml" );
344 }
345
346
347 if ( containerConfigXML != null && StringUtils.isNotEmpty( containerConfigXML.getName() ) )
348 {
349 excludeList.add( "**/" + META_INF + "/" + containerConfigXML.getName() );
350 }
351
352 return (String[]) excludeList.toArray( EMPTY_STRING_ARRAY );
353 }
354
355
356
357
358
359
360
361 protected String[] getIncludes()
362 {
363 return StringUtils.split( StringUtils.defaultString( warSourceIncludes ), "," );
364 }
365
366
367
368
369
370
371
372 protected String[] getDependentWarExcludes()
373 {
374 String[] excludes;
375 if ( StringUtils.isNotEmpty( dependentWarExcludes ) )
376 {
377 excludes = StringUtils.split( dependentWarExcludes, "," );
378 }
379 else
380 {
381 excludes = EMPTY_STRING_ARRAY;
382 }
383 return excludes;
384 }
385
386
387
388
389
390
391
392 protected String[] getDependentWarIncludes()
393 {
394 return StringUtils.split( StringUtils.defaultString( dependentWarIncludes ), "," );
395 }
396
397 public void buildExplodedWebapp( File webappDirectory )
398 throws MojoExecutionException, MojoFailureException
399 {
400 webappDirectory.mkdirs();
401
402 try
403 {
404 buildWebapp( project, webappDirectory );
405 }
406 catch ( IOException e )
407 {
408 throw new MojoExecutionException( "Could not build webapp", e );
409 }
410 }
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 public void buildWebapp( MavenProject project, File webappDirectory )
427 throws MojoExecutionException, MojoFailureException, IOException
428 {
429
430 WebappStructure cache;
431 if ( useCache && cacheFile.exists() )
432 {
433 cache = new WebappStructure( project.getDependencies(), webappStructureSerialier.fromXml( cacheFile ) );
434 }
435 else
436 {
437 cache = new WebappStructure( project.getDependencies(), null );
438 }
439
440 final long startTime = System.currentTimeMillis();
441 getLog().info( "Assembling webapp [" + project.getArtifactId() + "] in [" + webappDirectory + "]" );
442
443 final OverlayManager overlayManager =
444 new OverlayManager( overlays, project, dependentWarIncludes, dependentWarExcludes, currentProjectOverlay );
445 final List packagingTasks = getPackagingTasks( overlayManager );
446 List defaultFilterWrappers = null;
447 try
448 {
449 MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
450 mavenResourcesExecution.setEscapeString( escapeString );
451
452 defaultFilterWrappers = mavenFileFilter.getDefaultFilterWrappers( project, filters,
453 escapedBackslashesInFilePath,
454 this.session, mavenResourcesExecution );
455
456 }
457 catch ( MavenFilteringException e )
458 {
459 getLog().error( "fail to build filering wrappers " + e.getMessage() );
460 throw new MojoExecutionException( e.getMessage(), e );
461 }
462
463 final WarPackagingContext context = new DefaultWarPackagingContext( webappDirectory, cache, overlayManager,
464 defaultFilterWrappers,
465 getNonFilteredFileExtensions(),
466 filteringDeploymentDescriptors,
467 this.artifactFactory );
468 final Iterator it = packagingTasks.iterator();
469 while ( it.hasNext() )
470 {
471 WarPackagingTask warPackagingTask = (WarPackagingTask) it.next();
472 warPackagingTask.performPackaging( context );
473 }
474
475
476 final List postPackagingTasks = getPostPackagingTasks();
477 final Iterator it2 = postPackagingTasks.iterator();
478 while ( it2.hasNext() )
479 {
480 WarPostPackagingTask task = (WarPostPackagingTask) it2.next();
481 task.performPostPackaging( context );
482
483 }
484 getLog().info( "Webapp assembled in [" + ( System.currentTimeMillis() - startTime ) + " msecs]" );
485
486 }
487
488
489
490
491
492
493
494
495
496 private List getPackagingTasks( OverlayManager overlayManager )
497 throws MojoExecutionException
498 {
499 final List packagingTasks = new ArrayList();
500 if ( useCache )
501 {
502 packagingTasks.add( new DependenciesAnalysisPackagingTask() );
503 }
504
505 final List resolvedOverlays = overlayManager.getOverlays();
506 final Iterator it = resolvedOverlays.iterator();
507 while ( it.hasNext() )
508 {
509 Overlay overlay = (Overlay) it.next();
510 if ( overlay.isCurrentProject() )
511 {
512 packagingTasks.add( new WarProjectPackagingTask( webResources, webXml, containerConfigXML,
513 currentProjectOverlay ) );
514 }
515 else
516 {
517 packagingTasks.add( new OverlayPackagingTask( overlay, currentProjectOverlay ) );
518 }
519 }
520 return packagingTasks;
521 }
522
523
524
525
526
527
528
529
530 private List getPostPackagingTasks()
531 {
532 final List postPackagingTasks = new ArrayList();
533 if ( useCache )
534 {
535 postPackagingTasks.add( new SaveWebappStructurePostPackagingTask( cacheFile ) );
536 }
537
538 return postPackagingTasks;
539 }
540
541
542
543
544 private class DefaultWarPackagingContext
545 implements WarPackagingContext
546 {
547
548 private final ArtifactFactory artifactFactory;
549
550 private final WebappStructure webappStructure;
551
552 private final File webappDirectory;
553
554 private final OverlayManager overlayManager;
555
556 private final List filterWrappers;
557
558 private List nonFilteredFileExtensions;
559
560 private boolean filteringDeploymentDescriptors;
561
562 public DefaultWarPackagingContext( File webappDirectory, final WebappStructure webappStructure,
563 final OverlayManager overlayManager, List filterWrappers,
564 List nonFilteredFileExtensions, boolean filteringDeploymentDescriptors,
565 ArtifactFactory artifactFactory )
566 {
567 this.webappDirectory = webappDirectory;
568 this.webappStructure = webappStructure;
569 this.overlayManager = overlayManager;
570 this.filterWrappers = filterWrappers;
571 this.artifactFactory = artifactFactory;
572 this.filteringDeploymentDescriptors = filteringDeploymentDescriptors;
573 this.nonFilteredFileExtensions = nonFilteredFileExtensions == null ? Collections.EMPTY_LIST
574 : nonFilteredFileExtensions;
575
576
577 final Iterator it = overlayManager.getOverlayIds().iterator();
578 while ( it.hasNext() )
579 {
580 String overlayId = (String) it.next();
581 webappStructure.getStructure( overlayId );
582 }
583 }
584
585 public MavenProject getProject()
586 {
587 return project;
588 }
589
590 public File getWebappDirectory()
591 {
592 return webappDirectory;
593 }
594
595 public File getClassesDirectory()
596 {
597 return classesDirectory;
598 }
599
600 public Log getLog()
601 {
602 return AbstractWarMojo.this.getLog();
603 }
604
605 public String getOutputFileNameMapping()
606 {
607 return outputFileNameMapping;
608 }
609
610 public File getWebappSourceDirectory()
611 {
612 return warSourceDirectory;
613 }
614
615 public String[] getWebappSourceIncludes()
616 {
617 return getIncludes();
618 }
619
620 public String[] getWebappSourceExcludes()
621 {
622 return getExcludes();
623 }
624
625 public boolean archiveClasses()
626 {
627 return archiveClasses;
628 }
629
630 public File getOverlaysWorkDirectory()
631 {
632 return workDirectory;
633 }
634
635 public ArchiverManager getArchiverManager()
636 {
637 return archiverManager;
638 }
639
640 public MavenArchiveConfiguration getArchive()
641 {
642 return archive;
643 }
644
645 public JarArchiver getJarArchiver()
646 {
647 return jarArchiver;
648 }
649
650 public List getFilters()
651 {
652 return filters;
653 }
654
655 public WebappStructure getWebappStructure()
656 {
657 return webappStructure;
658 }
659
660 public List getOwnerIds()
661 {
662 return overlayManager.getOverlayIds();
663 }
664
665 public MavenFileFilter getMavenFileFilter()
666 {
667 return mavenFileFilter;
668 }
669
670 public List getFilterWrappers()
671 {
672 return filterWrappers;
673 }
674
675 public boolean isNonFilteredExtension( String fileName )
676 {
677 return !mavenResourcesFiltering.filteredFileExtension( fileName, nonFilteredFileExtensions );
678 }
679
680 public boolean isFilteringDeploymentDescriptors()
681 {
682 return filteringDeploymentDescriptors;
683 }
684
685 public ArtifactFactory getArtifactFactory()
686 {
687 return this.artifactFactory;
688 }
689
690 }
691
692 public MavenProject getProject()
693 {
694 return project;
695 }
696
697 public void setProject( MavenProject project )
698 {
699 this.project = project;
700 }
701
702 public File getClassesDirectory()
703 {
704 return classesDirectory;
705 }
706
707 public void setClassesDirectory( File classesDirectory )
708 {
709 this.classesDirectory = classesDirectory;
710 }
711
712 public File getWebappDirectory()
713 {
714 return webappDirectory;
715 }
716
717 public void setWebappDirectory( File webappDirectory )
718 {
719 this.webappDirectory = webappDirectory;
720 }
721
722 public File getWarSourceDirectory()
723 {
724 return warSourceDirectory;
725 }
726
727 public void setWarSourceDirectory( File warSourceDirectory )
728 {
729 this.warSourceDirectory = warSourceDirectory;
730 }
731
732 public File getWebXml()
733 {
734 return webXml;
735 }
736
737 public void setWebXml( File webXml )
738 {
739 this.webXml = webXml;
740 }
741
742 public File getContainerConfigXML()
743 {
744 return containerConfigXML;
745 }
746
747 public void setContainerConfigXML( File containerConfigXML )
748 {
749 this.containerConfigXML = containerConfigXML;
750 }
751
752 public String getOutputFileNameMapping()
753 {
754 return outputFileNameMapping;
755 }
756
757 public void setOutputFileNameMapping( String outputFileNameMapping )
758 {
759 this.outputFileNameMapping = outputFileNameMapping;
760 }
761
762 public List getOverlays()
763 {
764 return overlays;
765 }
766
767 public void setOverlays( List overlays )
768 {
769 this.overlays = overlays;
770 }
771
772 public void addOverlay( Overlay overlay )
773 {
774 overlays.add( overlay );
775 }
776
777 public boolean isArchiveClasses()
778 {
779 return archiveClasses;
780 }
781
782 public void setArchiveClasses( boolean archiveClasses )
783 {
784 this.archiveClasses = archiveClasses;
785 }
786
787 public JarArchiver getJarArchiver()
788 {
789 return jarArchiver;
790 }
791
792 public void setJarArchiver( JarArchiver jarArchiver )
793 {
794 this.jarArchiver = jarArchiver;
795 }
796
797 public Resource[] getWebResources()
798 {
799 return webResources;
800 }
801
802 public void setWebResources( Resource[] webResources )
803 {
804 this.webResources = webResources;
805 }
806
807 public List getFilters()
808 {
809 return filters;
810 }
811
812 public void setFilters( List filters )
813 {
814 this.filters = filters;
815 }
816
817 public File getWorkDirectory()
818 {
819 return workDirectory;
820 }
821
822 public void setWorkDirectory( File workDirectory )
823 {
824 this.workDirectory = workDirectory;
825 }
826
827 public File getCacheFile()
828 {
829 return cacheFile;
830 }
831
832 public void setCacheFile( File cacheFile )
833 {
834 this.cacheFile = cacheFile;
835 }
836
837 public String getWarSourceIncludes()
838 {
839 return warSourceIncludes;
840 }
841
842 public void setWarSourceIncludes( String warSourceIncludes )
843 {
844 this.warSourceIncludes = warSourceIncludes;
845 }
846
847 public String getWarSourceExcludes()
848 {
849 return warSourceExcludes;
850 }
851
852 public void setWarSourceExcludes( String warSourceExcludes )
853 {
854 this.warSourceExcludes = warSourceExcludes;
855 }
856
857
858 public boolean isUseCache()
859 {
860 return useCache;
861 }
862
863 public void setUseCache( boolean useCache )
864 {
865 this.useCache = useCache;
866 }
867
868 public MavenArchiveConfiguration getArchive()
869 {
870 return archive;
871 }
872
873 public List getNonFilteredFileExtensions()
874 {
875 return nonFilteredFileExtensions;
876 }
877
878 public void setNonFilteredFileExtensions( List nonFilteredFileExtensions )
879 {
880 this.nonFilteredFileExtensions = nonFilteredFileExtensions;
881 }
882
883 public ArtifactFactory getArtifactFactory()
884 {
885 return this.artifactFactory;
886 }
887
888 public void setArtifactFactory( ArtifactFactory artifactFactory )
889 {
890 this.artifactFactory = artifactFactory;
891 }
892 }