1 package org.apache.tomcat.maven.plugin.tomcat6;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import org.apache.catalina.Context;
24 import org.apache.catalina.Engine;
25 import org.apache.catalina.Host;
26 import org.apache.catalina.LifecycleException;
27 import org.apache.catalina.Wrapper;
28 import org.apache.catalina.connector.Connector;
29 import org.apache.catalina.loader.WebappLoader;
30 import org.apache.catalina.realm.MemoryRealm;
31 import org.apache.catalina.servlets.DefaultServlet;
32 import org.apache.catalina.startup.Catalina;
33 import org.apache.catalina.startup.Embedded;
34 import org.apache.maven.artifact.Artifact;
35 import org.apache.maven.artifact.factory.ArtifactFactory;
36 import org.apache.maven.artifact.repository.ArtifactRepository;
37 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
38 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
39 import org.apache.maven.artifact.resolver.ArtifactResolver;
40 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
41 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
42 import org.apache.maven.artifact.versioning.VersionRange;
43 import org.apache.maven.execution.MavenSession;
44 import org.apache.maven.plugin.MojoExecutionException;
45 import org.apache.maven.plugin.MojoFailureException;
46 import org.apache.maven.plugins.annotations.Component;
47 import org.apache.maven.plugins.annotations.Parameter;
48 import org.apache.maven.project.MavenProject;
49 import org.apache.maven.shared.filtering.MavenFileFilter;
50 import org.apache.maven.shared.filtering.MavenFileFilterRequest;
51 import org.apache.maven.shared.filtering.MavenFilteringException;
52 import org.apache.tomcat.maven.common.config.AbstractWebapp;
53 import org.apache.tomcat.maven.common.run.EmbeddedRegistry;
54 import org.codehaus.plexus.archiver.ArchiverException;
55 import org.codehaus.plexus.archiver.UnArchiver;
56 import org.codehaus.plexus.archiver.manager.ArchiverManager;
57 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
58 import org.codehaus.plexus.classworlds.ClassWorld;
59 import org.codehaus.plexus.classworlds.realm.ClassRealm;
60 import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
61 import org.codehaus.plexus.util.DirectoryScanner;
62 import org.codehaus.plexus.util.FileUtils;
63 import org.codehaus.plexus.util.StringUtils;
64 import org.w3c.dom.Document;
65 import org.w3c.dom.NamedNodeMap;
66 import org.w3c.dom.Node;
67 import org.xml.sax.SAXException;
68
69 import javax.xml.parsers.DocumentBuilder;
70 import javax.xml.parsers.DocumentBuilderFactory;
71 import javax.xml.parsers.ParserConfigurationException;
72 import java.io.File;
73 import java.io.FileNotFoundException;
74 import java.io.IOException;
75 import java.net.InetAddress;
76 import java.net.MalformedURLException;
77 import java.net.URL;
78 import java.util.ArrayList;
79 import java.util.Collection;
80 import java.util.Collections;
81 import java.util.List;
82 import java.util.Map;
83 import java.util.Set;
84
85
86
87
88
89
90
91 public abstract class AbstractRunMojo
92 extends AbstractI18NTomcat6Mojo
93 {
94
95
96
97
98
99
100
101 @Component( role = ArtifactFactory.class )
102 protected ArtifactFactory artifactFactory;
103
104
105
106
107 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
108 private ArtifactRepository artifactRepository;
109
110
111
112
113 @Component( role = ArtifactResolver.class )
114 protected ArtifactResolver artifactResolver;
115
116
117
118
119
120
121
122
123 @Parameter( defaultValue = "${project.packaging}", required = true, readonly = true )
124 private String packaging;
125
126
127
128
129 @Parameter( defaultValue = "${project.build.directory}/tomcat" )
130 private File configurationDir;
131
132
133
134
135 @Parameter( property = "maven.tomcat.port", defaultValue = "8080" )
136 private int port;
137
138
139
140
141
142
143
144
145 @Parameter( property = "maven.tomcat.ajp.port", defaultValue = "0" )
146 private int ajpPort;
147
148
149
150
151
152
153
154
155 @Parameter( property = "maven.tomcat.ajp.protocol", defaultValue = "ajp" )
156 private String ajpProtocol;
157
158
159
160
161
162
163
164
165 @Parameter( property = "maven.tomcat.httpsPort", defaultValue = "0" )
166 private int httpsPort;
167
168
169
170
171
172
173 @Parameter( property = "maven.tomcat.uriEncoding", defaultValue = "ISO-8859-1" )
174 private String uriEncoding;
175
176
177
178
179
180
181 @Parameter
182 private Map<String, String> systemProperties;
183
184
185
186
187
188
189 @Parameter( property = "maven.tomcat.additionalConfigFilesDir", defaultValue = "${basedir}/src/main/tomcatconf" )
190 private File additionalConfigFilesDir;
191
192
193
194
195
196
197 @Parameter( property = "maven.tomcat.serverXml" )
198 private File serverXml;
199
200
201
202
203
204
205 @Parameter( property = "maven.tomcat.webXml" )
206 private File tomcatWebXml;
207
208
209
210
211
212
213
214 @Parameter( property = "maven.tomcat.fork", defaultValue = "false" )
215 private boolean fork;
216
217
218
219
220
221
222
223
224
225
226
227
228
229 @Parameter( property = "maven.tomcat.addContextWarDependencies", defaultValue = "false" )
230 private boolean addContextWarDependencies;
231
232
233
234
235
236
237 @Component
238 protected MavenProject project;
239
240
241
242
243
244
245 @Component( role = ArchiverManager.class )
246 private ArchiverManager archiverManager;
247
248
249
250
251
252
253 @Parameter( property = "tomcat.useSeparateTomcatClassLoader", defaultValue = "false" )
254 protected boolean useSeparateTomcatClassLoader;
255
256
257
258
259 @Parameter( defaultValue = "${plugin.artifacts}", required = true )
260 private List<Artifact> pluginArtifacts;
261
262
263
264
265
266
267 @Parameter( property = "tomcat.ignorePackaging", defaultValue = "false" )
268 private boolean ignorePackaging;
269
270
271
272
273
274
275 @Parameter
276 private String keystoreFile;
277
278
279
280
281
282
283 @Parameter
284 private String keystorePass;
285
286
287
288
289
290
291 @Parameter( defaultValue = "JKS" )
292 private String keystoreType;
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308 @Parameter( property = "maven.tomcat.useNaming", defaultValue = "true" )
309 private boolean useNaming;
310
311
312
313
314
315
316
317
318 @Parameter( property = "maven.tomcat.contextReloadable", defaultValue = "false" )
319 protected boolean contextReloadable;
320
321
322
323
324
325
326 @Parameter( property = "maven.tomcat.backgroundProcessorDelay", defaultValue = "-1" )
327 protected int backgroundProcessorDelay = -1;
328
329
330
331
332 @Parameter( defaultValue = "src/main/webapp/META-INF/context.xml" )
333 protected File contextFile;
334
335
336
337
338
339
340
341 @Parameter( property = "maven.tomcat.protocol", defaultValue = "HTTP/1.1" )
342 private String protocol;
343
344
345
346
347 @Parameter( property = "maven.tomcat.tomcatUsers.file" )
348 private File tomcatUsers;
349
350
351
352
353
354
355 @Parameter
356 private File managerWarPath;
357
358
359
360
361
362
363
364 @Parameter( property = "maven.tomcat.skip", defaultValue = "false" )
365 protected boolean skip;
366
367
368
369
370
371 @Parameter
372 private List<Webapp> webapps;
373
374
375
376
377
378
379 @Parameter( property = "maven.tomcat.hostName", defaultValue = "localhost" )
380 protected String hostName;
381
382
383
384
385
386
387
388 @Parameter
389 protected String[] aliases;
390
391
392
393
394
395
396
397
398 private ClassRealm tomcatRealm;
399
400
401
402
403
404
405 @Parameter( property = "maven.tomcat.staticContextPath", defaultValue = "/" )
406 private String staticContextPath;
407
408
409
410
411
412
413
414 @Parameter( property = "maven.tomcat.staticContextDocbase" )
415 private String staticContextDocbase;
416
417
418
419
420
421
422 @Parameter
423 protected String classLoaderClass;
424
425 @Parameter( defaultValue = "${session}", readonly = true, required = true )
426 protected MavenSession session;
427
428 @Component( role = MavenFileFilter.class, hint = "default" )
429 protected MavenFileFilter mavenFileFilter;
430
431
432
433
434
435
436
437
438 public void execute()
439 throws MojoExecutionException, MojoFailureException
440 {
441 if ( skip )
442 {
443 getLog().info( "skip execution" );
444 return;
445 }
446
447 if ( !isWar() && !addContextWarDependencies && getAdditionalWebapps().isEmpty() )
448 {
449 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.nonWar" ) );
450 return;
451 }
452 ClassLoader originalClassLoader = null;
453 try
454 {
455
456 if ( useSeparateTomcatClassLoader )
457 {
458 originalClassLoader = Thread.currentThread().getContextClassLoader();
459 }
460 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.runningWar", getWebappUrl() ) );
461
462 initConfiguration();
463 startContainer();
464 if ( !fork )
465 {
466 waitIndefinitely();
467 }
468 }
469 catch ( LifecycleException exception )
470 {
471 throw new MojoExecutionException( messagesProvider.getMessage( "AbstractRunMojo.cannotStart" ), exception );
472 }
473 catch ( IOException exception )
474 {
475 throw new MojoExecutionException(
476 messagesProvider.getMessage( "AbstractRunMojo.cannotCreateConfiguration" ), exception );
477 }
478 catch ( MavenFilteringException e )
479 {
480 throw new MojoExecutionException( "filtering issue: " + e.getMessage(), e );
481 }
482 finally
483 {
484 if ( useSeparateTomcatClassLoader )
485 {
486 Thread.currentThread().setContextClassLoader( originalClassLoader );
487 }
488 }
489 }
490
491
492
493
494
495
496
497
498
499
500 protected String getPath()
501 {
502 return path;
503 }
504
505
506
507
508
509
510
511
512
513 protected Context createContext( Embedded container )
514 throws IOException, MojoExecutionException
515 {
516 String contextPath = getPath();
517 Context context =
518 container.createContext( "/".equals( contextPath ) ? "" : contextPath, getDocBase().getAbsolutePath() );
519
520 if ( useSeparateTomcatClassLoader )
521 {
522 context.setParentClassLoader( getTomcatClassLoader() );
523 }
524
525 final WebappLoader webappLoader = createWebappLoader();
526
527 if ( classLoaderClass != null )
528 {
529 webappLoader.setLoaderClass( classLoaderClass );
530 }
531
532 context.setLoader( webappLoader );
533 File contextFile = getContextFile();
534 if ( contextFile != null )
535 {
536 context.setConfigFile( getContextFile().getAbsolutePath() );
537 }
538 return context;
539 }
540
541
542
543
544
545
546
547
548 protected WebappLoader createWebappLoader()
549 throws IOException, MojoExecutionException
550 {
551 if ( useSeparateTomcatClassLoader )
552 {
553 return ( isContextReloadable() )
554 ? new ExternalRepositoriesReloadableWebappLoader( getTomcatClassLoader(), getLog() )
555 : new WebappLoader( getTomcatClassLoader() );
556 }
557
558 return ( isContextReloadable() )
559 ? new ExternalRepositoriesReloadableWebappLoader( Thread.currentThread().getContextClassLoader(), getLog() )
560 : new WebappLoader( Thread.currentThread().getContextClassLoader() );
561 }
562
563
564
565
566
567
568 protected boolean isContextReloadable()
569 throws MojoExecutionException
570 {
571 if ( contextReloadable || backgroundProcessorDelay > 0 )
572 {
573 return true;
574 }
575
576 boolean reloadable = false;
577 try
578 {
579 if ( contextFile != null && contextFile.exists() )
580 {
581 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
582 DocumentBuilder builder = builderFactory.newDocumentBuilder();
583 Document contextDoc = builder.parse( contextFile );
584 contextDoc.getDocumentElement().normalize();
585
586 NamedNodeMap nodeMap = contextDoc.getDocumentElement().getAttributes();
587 Node reloadableAttribute = nodeMap.getNamedItem( "reloadable" );
588
589 reloadable =
590 ( reloadableAttribute != null ) ? Boolean.valueOf( reloadableAttribute.getNodeValue() ) : false;
591 }
592 getLog().debug( "context reloadable: " + reloadable );
593 }
594 catch ( IOException ioe )
595 {
596 getLog().error( "Could not parse file: [" + contextFile.getAbsolutePath() + "]", ioe );
597 }
598 catch ( ParserConfigurationException pce )
599 {
600 getLog().error( "Could not configure XML parser", pce );
601 }
602 catch ( SAXException se )
603 {
604 getLog().error( "Could not parse file: [" + contextFile.getAbsolutePath() + "]", se );
605 }
606
607 return reloadable;
608 }
609
610
611
612
613
614
615
616 protected abstract File getDocBase();
617
618
619
620
621
622
623 protected abstract File getContextFile()
624 throws MojoExecutionException;
625
626
627
628
629
630
631
632
633
634
635 protected boolean isWar()
636 {
637 return "war".equals( packaging ) || ignorePackaging;
638 }
639
640
641
642
643
644
645
646 private URL getWebappUrl()
647 throws MalformedURLException
648 {
649 return new URL( "http", "localhost", port, getPath() );
650 }
651
652
653
654
655
656
657
658 private void initConfiguration()
659 throws IOException, MojoExecutionException, MavenFilteringException
660 {
661 if ( configurationDir.exists() )
662 {
663 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.usingConfiguration", configurationDir ) );
664 }
665 else
666 {
667 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.creatingConfiguration", configurationDir ) );
668
669 configurationDir.mkdirs();
670
671 File confDir = new File( configurationDir, "conf" );
672 confDir.mkdir();
673
674 copyFile( "/conf/tomcat-users.xml", new File( confDir, "tomcat-users.xml" ) );
675
676 if ( tomcatWebXml != null )
677 {
678 if ( !tomcatWebXml.exists() )
679 {
680 throw new MojoExecutionException( " tomcatWebXml " + tomcatWebXml.getPath() + " not exists" );
681 }
682
683 FileUtils.copyFile( tomcatWebXml, new File( confDir, "web.xml" ) );
684
685 MavenFileFilterRequest mavenFileFilterRequest = new MavenFileFilterRequest();
686 mavenFileFilterRequest.setFrom( tomcatWebXml );
687 mavenFileFilterRequest.setTo( new File( confDir, "web.xml" ) );
688 mavenFileFilterRequest.setMavenProject( project );
689 mavenFileFilterRequest.setMavenSession( session );
690 mavenFileFilterRequest.setFiltering( true );
691
692 mavenFileFilter.copyFile( mavenFileFilterRequest );
693 }
694 else
695 {
696 copyFile( "/conf/web.xml", new File( confDir, "web.xml" ) );
697 }
698
699 File logDir = new File( configurationDir, "logs" );
700 logDir.mkdir();
701
702 File webappsDir = new File( configurationDir, "webapps" );
703 webappsDir.mkdir();
704 if ( managerWarPath != null && managerWarPath.exists() )
705 {
706 FileUtils.copyFileToDirectory( managerWarPath, webappsDir );
707 }
708
709 if ( additionalConfigFilesDir != null && additionalConfigFilesDir.exists() )
710 {
711 DirectoryScanner scanner = new DirectoryScanner();
712 scanner.addDefaultExcludes();
713 scanner.setBasedir( additionalConfigFilesDir.getPath() );
714 scanner.scan();
715
716 String[] files = scanner.getIncludedFiles();
717
718 if ( files != null && files.length > 0 )
719 {
720 getLog().info( "Coping additional tomcat config files" );
721
722 for ( int i = 0; i < files.length; i++ )
723 {
724 File file = new File( additionalConfigFilesDir, files[i] );
725
726 getLog().info( " copy " + file.getName() );
727
728 FileUtils.copyFileToDirectory( file, confDir );
729 }
730 }
731 }
732 }
733 }
734
735
736
737
738
739
740
741
742 private void copyFile( String fromPath, File toFile )
743 throws IOException
744 {
745 URL fromURL = getClass().getResource( fromPath );
746
747 if ( fromURL == null )
748 {
749 throw new FileNotFoundException( fromPath );
750 }
751
752 FileUtils.copyURLToFile( fromURL, toFile );
753 }
754
755
756
757
758
759
760
761
762 private void startContainer()
763 throws IOException, LifecycleException, MojoExecutionException
764 {
765 String previousCatalinaBase = System.getProperty( "catalina.base" );
766
767 try
768 {
769
770
771 setupSystemProperties();
772
773 System.setProperty( "catalina.base", configurationDir.getAbsolutePath() );
774 System.setProperty( "catalina.home", configurationDir.getAbsolutePath() );
775
776 File catalinaPolicy = new File( configurationDir, "conf/catalina.policy" );
777
778 if ( catalinaPolicy.exists() )
779 {
780
781 System.setProperty( "java.security.policy", catalinaPolicy.getAbsolutePath() );
782 }
783
784 final Embedded container;
785 if ( serverXml != null )
786 {
787 if ( !serverXml.exists() )
788 {
789 throw new MojoExecutionException( serverXml.getPath() + " not exists" );
790 }
791
792 container = new Catalina();
793 container.setCatalinaHome( configurationDir.getAbsolutePath() );
794 container.setCatalinaBase( configurationDir.getAbsolutePath() );
795 ( (Catalina) container ).setConfigFile( serverXml.getPath() );
796 ( (Catalina) container ).setRedirectStreams( true );
797 ( (Catalina) container ).setUseNaming( this.useNaming );
798
799 container.start();
800 }
801 else
802 {
803
804 container = new Embedded();
805 container.setCatalinaHome( configurationDir.getAbsolutePath() );
806 MemoryRealm memoryRealm = new MemoryRealm();
807
808 if ( tomcatUsers != null )
809 {
810 if ( !tomcatUsers.exists() )
811 {
812 throw new MojoExecutionException( " tomcatUsers " + tomcatUsers.getPath() + " not exists" );
813 }
814 getLog().info( "use tomcat-users.xml from " + tomcatUsers.getAbsolutePath() );
815 memoryRealm.setPathname( tomcatUsers.getAbsolutePath() );
816
817 }
818
819 container.setRealm( memoryRealm );
820 container.setUseNaming( useNaming );
821
822
823
824
825 Context context = createContext( container );
826
827
828 String appBase = new File( configurationDir, "webapps" ).getAbsolutePath();
829 Host host = container.createHost( "localHost", appBase );
830
831 if ( hostName != null )
832 {
833 host.setName( hostName );
834 }
835 if ( aliases != null )
836 {
837 for ( String alias : aliases )
838 {
839 host.addAlias( alias );
840 }
841 }
842
843 host.addChild( context );
844 createStaticContext( container, context, host );
845 if ( addContextWarDependencies || !getAdditionalWebapps().isEmpty() )
846 {
847 Collection<Context> dependencyContexts = createDependencyContexts( container );
848 for ( Context extraContext : dependencyContexts )
849 {
850 host.addChild( extraContext );
851 }
852 }
853
854
855 Engine engine = container.createEngine();
856 engine.setName( "localEngine-" + port );
857 engine.addChild( host );
858 engine.setDefaultHost( host.getName() );
859 container.addEngine( engine );
860
861 getLog().debug( "start tomcat instance on http port:" + port + " and protocol: " + protocol );
862
863
864 Connector httpConnector = container.createConnector( (InetAddress) null, port, protocol );
865 if ( httpsPort > 0 )
866 {
867 httpConnector.setRedirectPort( httpsPort );
868 }
869 httpConnector.setURIEncoding( uriEncoding );
870 container.addConnector( httpConnector );
871
872
873 if ( httpsPort > 0 )
874 {
875 Connector httpsConnector = container.createConnector( (InetAddress) null, httpsPort, true );
876 httpsConnector.setSecure( true );
877 httpsConnector.setProperty( "SSLEnabled", "true" );
878
879 httpsConnector.setProperty( "sslProtocol", "TLS" );
880 if ( keystoreFile != null )
881 {
882 httpsConnector.setAttribute( "keystoreFile", keystoreFile );
883 }
884 if ( keystorePass != null )
885 {
886 httpsConnector.setAttribute( "keystorePass", keystorePass );
887 }
888 if ( keystoreType != null )
889 {
890 httpsConnector.setAttribute( "keystoreType", keystoreType );
891 }
892 container.addConnector( httpsConnector );
893
894 }
895
896
897 if ( ajpPort > 0 )
898 {
899 Connector ajpConnector = container.createConnector( (InetAddress) null, ajpPort, ajpProtocol );
900 ajpConnector.setURIEncoding( uriEncoding );
901 container.addConnector( ajpConnector );
902 }
903 if ( useSeparateTomcatClassLoader )
904 {
905 Thread.currentThread().setContextClassLoader( getTomcatClassLoader() );
906 engine.setParentClassLoader( getTomcatClassLoader() );
907 }
908 container.start();
909 }
910
911 EmbeddedRegistry.getInstance().register( container );
912 }
913 finally
914 {
915 if ( previousCatalinaBase != null )
916 {
917 System.setProperty( "catalina.base", previousCatalinaBase );
918 }
919 }
920 }
921
922 private List<Webapp> getAdditionalWebapps()
923 {
924 if ( webapps == null )
925 {
926 return Collections.emptyList();
927 }
928 return webapps;
929 }
930
931 protected ClassRealm getTomcatClassLoader()
932 throws MojoExecutionException
933 {
934 if ( this.tomcatRealm != null )
935 {
936 return tomcatRealm;
937 }
938 try
939 {
940 ClassWorld world = new ClassWorld();
941 ClassRealm root = world.newRealm( "tomcat", Thread.currentThread().getContextClassLoader() );
942
943 for ( Artifact pluginArtifact : pluginArtifacts )
944 {
945
946 if ( pluginArtifact.getFile() != null )
947 {
948 root.addURL( pluginArtifact.getFile().toURI().toURL() );
949 }
950
951 }
952 tomcatRealm = root;
953 return root;
954 }
955 catch ( DuplicateRealmException e )
956 {
957 throw new MojoExecutionException( e.getMessage(), e );
958 }
959 catch ( MalformedURLException e )
960 {
961 throw new MojoExecutionException( e.getMessage(), e );
962 }
963 }
964
965 @SuppressWarnings( "unchecked" )
966 public Set<Artifact> getProjectArtifacts()
967 {
968 return project.getArtifacts();
969 }
970
971
972
973
974 private void waitIndefinitely()
975 {
976 Object lock = new Object();
977
978 synchronized ( lock )
979 {
980 try
981 {
982 lock.wait();
983 }
984 catch ( InterruptedException exception )
985 {
986 getLog().warn( messagesProvider.getMessage( "AbstractRunMojo.interrupted" ), exception );
987 }
988 }
989 }
990
991
992
993
994
995 private void setupSystemProperties()
996 {
997 if ( systemProperties != null && !systemProperties.isEmpty() )
998 {
999 getLog().info( "setting SystemProperties:" );
1000
1001 for ( String key : systemProperties.keySet() )
1002 {
1003 String value = systemProperties.get( key );
1004
1005 if ( value != null )
1006 {
1007 getLog().info( " " + key + "=" + value );
1008 System.setProperty( key, value );
1009 }
1010 else
1011 {
1012 getLog().info( "skip sysProps " + key + " with empty value" );
1013 }
1014 }
1015 }
1016 }
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026 private Collection<Context> createDependencyContexts( Embedded container )
1027 throws MojoExecutionException
1028 {
1029 getLog().info( "Deploying dependency wars" );
1030
1031 List<Context> contexts = new ArrayList<Context>();
1032
1033 ScopeArtifactFilter filter = new ScopeArtifactFilter( "tomcat" );
1034 @SuppressWarnings( "unchecked" ) Set<Artifact> artifacts = project.getArtifacts();
1035 for ( Artifact artifact : artifacts )
1036 {
1037
1038
1039 if ( "war".equals( artifact.getType() ) && !artifact.isOptional() && filter.include( artifact ) )
1040 {
1041 addContextFromArtifact( container, contexts, artifact, "/" + artifact.getArtifactId(), null );
1042 }
1043 }
1044
1045 for ( AbstractWebapp additionalWebapp : getAdditionalWebapps() )
1046 {
1047 String contextPath = additionalWebapp.getContextPath();
1048 if ( !contextPath.startsWith( "/" ) )
1049 {
1050 contextPath = "/" + contextPath;
1051 }
1052 addContextFromArtifact( container, contexts, getArtifact( additionalWebapp ), contextPath,
1053 additionalWebapp.getContextFile() );
1054 }
1055 return contexts;
1056 }
1057
1058
1059 private void addContextFromArtifact( Embedded container, List<Context> contexts, Artifact artifact,
1060 String contextPath, File contextXml )
1061 throws MojoExecutionException
1062 {
1063 getLog().info( "Deploy warfile: " + String.valueOf( artifact.getFile() ) + " to contextPath: " + contextPath );
1064 File webapps = new File( configurationDir, "webapps" );
1065 File artifactWarDir = new File( webapps, artifact.getArtifactId() );
1066 if ( !artifactWarDir.exists() )
1067 {
1068
1069 artifactWarDir.mkdir();
1070 try
1071 {
1072 UnArchiver unArchiver = archiverManager.getUnArchiver( "zip" );
1073 unArchiver.setSourceFile( artifact.getFile() );
1074 unArchiver.setDestDirectory( artifactWarDir );
1075
1076
1077 unArchiver.extract();
1078 }
1079 catch ( NoSuchArchiverException e )
1080 {
1081 getLog().error( e );
1082 return;
1083 }
1084 catch ( ArchiverException e )
1085 {
1086 getLog().error( e );
1087 return;
1088 }
1089 }
1090 WebappLoader webappLoader = new WebappLoader( Thread.currentThread().getContextClassLoader() );
1091 Context context = container.createContext( contextPath, artifactWarDir.getAbsolutePath() );
1092 context.setLoader( webappLoader );
1093
1094 File contextFile = contextXml != null ? contextXml : getContextFile();
1095 if ( contextFile != null )
1096 {
1097 context.setConfigFile( contextFile.getAbsolutePath() );
1098 }
1099 contexts.add( context );
1100 }
1101
1102
1103 private void createStaticContext( final Embedded container, Context context, Host host )
1104 {
1105 if ( staticContextDocbase != null )
1106 {
1107 Context staticContext = container.createContext( staticContextPath, staticContextDocbase );
1108 staticContext.setPrivileged( true );
1109 Wrapper servlet = context.createWrapper();
1110 servlet.setServletClass( DefaultServlet.class.getName() );
1111 servlet.setName( "staticContent" );
1112 staticContext.addChild( servlet );
1113 staticContext.addServletMapping( "/", "staticContent" );
1114 host.addChild( staticContext );
1115 }
1116 }
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127 protected Artifact getArtifact( AbstractWebapp additionalWebapp )
1128 throws MojoExecutionException
1129 {
1130
1131 Artifact artifact;
1132 VersionRange vr;
1133 try
1134 {
1135 vr = VersionRange.createFromVersionSpec( additionalWebapp.getVersion() );
1136 }
1137 catch ( InvalidVersionSpecificationException e )
1138 {
1139 getLog().warn( "fail to create versionRange from version: " + additionalWebapp.getVersion(), e );
1140 vr = VersionRange.createFromVersion( additionalWebapp.getVersion() );
1141 }
1142
1143 if ( StringUtils.isEmpty( additionalWebapp.getClassifier() ) )
1144 {
1145 artifact = artifactFactory.createDependencyArtifact( additionalWebapp.getGroupId(),
1146 additionalWebapp.getArtifactId(), vr,
1147 additionalWebapp.getType(), null,
1148 Artifact.SCOPE_COMPILE );
1149 }
1150 else
1151 {
1152 artifact = artifactFactory.createDependencyArtifact( additionalWebapp.getGroupId(),
1153 additionalWebapp.getArtifactId(), vr,
1154 additionalWebapp.getType(),
1155 additionalWebapp.getClassifier(),
1156 Artifact.SCOPE_COMPILE );
1157 }
1158
1159 try
1160 {
1161 artifactResolver.resolve( artifact, project.getRemoteArtifactRepositories(), this.artifactRepository );
1162 }
1163 catch ( ArtifactResolutionException e )
1164 {
1165 throw new MojoExecutionException( "Unable to resolve artifact.", e );
1166 }
1167 catch ( ArtifactNotFoundException e )
1168 {
1169 throw new MojoExecutionException( "Unable to find artifact.", e );
1170 }
1171
1172 return artifact;
1173 }
1174 }