View Javadoc
1   package org.codehaus.mojo.gwt.webxml;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.io.FileUtils;
23  import org.apache.commons.lang.StringUtils;
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.MojoFailureException;
26  import org.apache.maven.plugins.annotations.Component;
27  import org.apache.maven.plugins.annotations.LifecyclePhase;
28  import org.apache.maven.plugins.annotations.Mojo;
29  import org.apache.maven.plugins.annotations.Parameter;
30  import org.apache.maven.plugins.annotations.ResolutionScope;
31  import org.codehaus.mojo.gwt.GwtModule;
32  import org.codehaus.mojo.gwt.shell.AbstractGwtWebMojo;
33  
34  import java.io.File;
35  import java.net.MalformedURLException;
36  import java.net.URL;
37  import java.net.URLClassLoader;
38  import java.util.LinkedHashSet;
39  import java.util.Map;
40  import java.util.Set;
41  
42  /**
43   * Merges GWT servlet elements into deployment descriptor (and non GWT servlets into shell).
44   * <p>
45   * <b>If you use {@link #scanRemoteServiceRelativePathAnnotation} you must bind this mojo to at least compile phase</b>
46   * Because the classpath scanner need to see compile classes
47   * 
48   * @author cooper
49   * @version $Id$
50   */
51  @Mojo(name = "mergewebxml", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresDependencyResolution = ResolutionScope.COMPILE, threadSafe = true)
52  public class MergeWebXmlMojo
53      extends AbstractGwtWebMojo
54  {
55  
56      /**
57       * Location on filesystem where merged web.xml will be created. The maven-war-plugin must be configured to use this
58       * path as <a href="http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#webXml"> webXml</a> parameter
59       */
60      @Parameter(defaultValue = "${project.build.directory}/web.xml")
61      private File mergedWebXml;
62  
63      /**
64       * @since 2.1.0-1
65       */
66      @Parameter(defaultValue = "false")
67      private boolean scanRemoteServiceRelativePathAnnotation;
68  
69      /**
70       * @since 2.1.0-1
71       */
72      @Parameter
73      private Map<String,String> packageNamePerModule;
74  
75      /**
76       * @since 2.1.0-1
77       */
78      @Component
79      private ServletAnnotationFinder servletAnnotationFinder;
80  
81      @Override
82      protected boolean isGenerator() {
83          return true;
84      }
85  
86      
87      public void doExecute()
88          throws MojoExecutionException, MojoFailureException
89      {
90  
91          if ( "pom".equals( getProject().getPackaging() ) )
92          {
93              getLog().info( "GWT mergewebxml is skipped" );
94              return;
95          }
96  
97          try
98          {
99              if ( !mergedWebXml.exists() )
100             {
101                 mergedWebXml.getParentFile().mkdirs();
102                 mergedWebXml.createNewFile();
103             }
104 
105             FileUtils.copyFile( getWebXml(), mergedWebXml );
106 
107             Set<ServletDescriptor> servlets = new LinkedHashSet<ServletDescriptor>();
108             
109 
110             for ( String module : getModules() )
111             {
112                 GwtModule gwtModule = readModule( module );
113 
114                 Map<String, String> moduleServlets = isWebXmlServletPathAsIs() ? gwtModule.getServlets( "" )
115                                                                               : gwtModule.getServlets();
116                 getLog().debug( "merge " + moduleServlets.size() + " servlets from module " + module );
117                 for ( Map.Entry<String, String> servlet : moduleServlets.entrySet() )
118                 {
119                     servlets.add( new ServletDescriptor( servlet.getKey(), servlet.getValue() ) );
120                 }
121 
122                 if ( scanRemoteServiceRelativePathAnnotation && packageNamePerModule != null )
123                 {
124                     String packageName = packageNamePerModule.get( gwtModule.getName() );
125                     if ( StringUtils.isBlank( packageName ) )
126                     {
127                         // here with try with the rename-to value
128                         packageName = packageNamePerModule.get( gwtModule.getPath() );
129                     }
130                     if ( StringUtils.isNotBlank( packageName ) )
131                     {
132                         getLog().debug( "search annotated servlet with package name " + packageName + " in module "
133                                             + gwtModule.getName() );
134                         Set<ServletDescriptor> annotatedServlets = servletAnnotationFinder
135                             .findServlets( packageName, isWebXmlServletPathAsIs() ? null : gwtModule.getPath(), getAnnotationSearchClassLoader() );
136                         servlets.addAll( annotatedServlets );
137                     } else
138                     {
139                         getLog().debug( "cannot find package name for module " + gwtModule.getName() + " or path "
140                                             + gwtModule.getPath() );
141                     }
142                 }
143 
144             }
145 
146             new GwtWebInfProcessor().process( mergedWebXml, mergedWebXml, servlets );
147             getLog().info( servlets.size() + " servlet(s) merged into " + mergedWebXml );
148         }
149         catch ( Exception e )
150         {
151             throw new MojoExecutionException( "Unable to merge web.xml", e );
152         }
153     }
154     
155     private ClassLoader getAnnotationSearchClassLoader()
156         throws MalformedURLException
157     {
158 
159         return new URLClassLoader( new URL[] { new File( getProject().getBuild().getOutputDirectory() ).toURI().toURL() } );
160 
161     }
162 }