View Javadoc

1   package org.apache.maven.plugin.ear;
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.maven.plugin.MojoExecutionException;
23  import org.apache.maven.plugin.MojoFailureException;
24  import org.apache.maven.plugin.ear.util.JavaEEVersion;
25  import org.apache.maven.plugins.annotations.LifecyclePhase;
26  import org.apache.maven.plugins.annotations.Mojo;
27  import org.apache.maven.plugins.annotations.Parameter;
28  import org.apache.maven.plugins.annotations.ResolutionScope;
29  import org.codehaus.plexus.configuration.PlexusConfiguration;
30  import org.codehaus.plexus.configuration.PlexusConfigurationException;
31  import org.codehaus.plexus.util.FileUtils;
32  
33  import java.io.File;
34  import java.io.IOException;
35  import java.util.ArrayList;
36  import java.util.Arrays;
37  import java.util.List;
38  
39  /**
40   * Generates the EAR deployment descriptor file(s).
41   * 
42   * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
43   * @version $Id: GenerateApplicationXmlMojo.java 1542508 2013-11-16 13:21:35Z rfscholte $
44   */
45  @Mojo( name = "generate-application-xml", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, threadSafe = true, requiresDependencyResolution = ResolutionScope.TEST )
46  public class GenerateApplicationXmlMojo
47      extends AbstractEarMojo
48  {
49  
50      public static final String DEFAULT = "DEFAULT";
51  
52      public static final String EMPTY = "EMPTY";
53  
54      public static final String NONE = "NONE";
55  
56      /**
57       * Whether the application.xml should be generated or not.
58       */
59      @Parameter( defaultValue = "true" )
60      private Boolean generateApplicationXml = Boolean.TRUE;
61  
62      /**
63       * Whether a module ID should be generated if none is specified.
64       */
65      @Parameter( defaultValue = "false" )
66      private Boolean generateModuleId = Boolean.FALSE;
67  
68      /**
69       * Application name of the application to be used when the application.xml file is auto-generated. Since JavaEE6.
70       */
71      @Parameter
72      private String applicationName;
73  
74      /**
75       * Display name of the application to be used when the application.xml file is auto-generated.
76       */
77      @Parameter( defaultValue = "${project.artifactId}" )
78      private String displayName;
79  
80      /**
81       * Description of the application to be used when the application.xml file is auto-generated.
82       */
83      @Parameter( defaultValue = "${project.description}" )
84      private String description;
85  
86      /**
87       * Defines how the <tt>library-directory</tt> element should be written in the application.xml file.
88       * <p/>
89       * Three special values can be set:
90       * <ul>
91       * <li><code>DEFAULT</code> (default) generates a <tt>library-directory</tt> element with the value of the
92       * <tt>defaultLibBundleDir</tt> parameter</li>
93       * <li><code>EMPTY</code> generates an empty <tt>library-directory</tt> element. Per spec, this disables the
94       * scanning of jar files in the <tt>lib</tt> directory of the ear file</li>
95       * <li><code>NONE</code> does not write the library-directory element at all. A corner case that can be used in
96       * Oracle Weblogic to delegate the classloading to the container</li>
97       * </ul>
98       * <p/>
99       * Since JavaEE5.
100      */
101     @Parameter( defaultValue = DEFAULT )
102     private String libraryDirectoryMode;
103 
104     /**
105      * Defines the value of the initialize in order element to be used when the application.xml file is auto-generated.
106      * When set to true, modules must be initialized in the order they're listed in this deployment descriptor, with the
107      * exception of application client modules, which can be initialized in any order. If initialize-in-order is not set
108      * or set to false, the order of initialization is unspecified and may be product-dependent. Since JavaEE6.
109      */
110     @Parameter
111     private Boolean initializeInOrder;
112 
113     /**
114      * Defines the application id used when generating the deployment descriptor.
115      * 
116      * @since 2.9
117      */
118     @Parameter
119     private String applicationId;
120 
121     /**
122      * The security-roles to be added to the auto-generated application.xml file.
123      */
124     @Parameter
125     private PlexusConfiguration security;
126 
127     /**
128      * The env-entries to be added to the auto-generated application.xml file. Since JavaEE6.
129      */
130     @Parameter( alias = "env-entries" )
131     private PlexusConfiguration envEntries;
132 
133     public void execute()
134         throws MojoExecutionException, MojoFailureException
135     {
136         // Initializes ear modules
137         super.execute();
138 
139         // Handle application.xml
140         if ( !generateApplicationXml )
141         {
142             getLog().debug( "Generation of application.xml is disabled" );
143         }
144         else
145         {
146             final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );
147 
148             // Generate deployment descriptor and copy it to the build directory
149             getLog().info( "Generating application.xml" );
150             try
151             {
152                 generateStandardDeploymentDescriptor( javaEEVersion );
153             }
154             catch ( EarPluginException e )
155             {
156                 throw new MojoExecutionException( "Failed to generate application.xml", e );
157             }
158 
159             try
160             {
161                 FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "application.xml" ),
162                                                new File( getWorkDirectory(), "META-INF" ) );
163             }
164             catch ( IOException e )
165             {
166                 throw new MojoExecutionException( "Unable to copy application.xml to final destination", e );
167             }
168         }
169 
170         // Handle jboss-app.xml
171         if ( getJbossConfiguration() == null )
172         {
173             getLog().debug( "Generation of jboss-app.xml is disabled" );
174         }
175         else
176         {
177             // Generate deployment descriptor and copy it to the build directory
178             getLog().info( "Generating jboss-app.xml" );
179             try
180             {
181                 generateJbossDeploymentDescriptor();
182             }
183             catch ( EarPluginException e )
184             {
185                 throw new MojoExecutionException( "Failed to generate jboss-app.xml", e );
186             }
187 
188             try
189             {
190                 FileUtils.copyFileToDirectory( new File( generatedDescriptorLocation, "jboss-app.xml" ),
191                                                new File( getWorkDirectory(), "META-INF" ) );
192             }
193             catch ( IOException e )
194             {
195                 throw new MojoExecutionException( "Unable to copy jboss-app.xml to final destination", e );
196             }
197         }
198     }
199 
200     /**
201      * Generates the deployment descriptor.
202      */
203     protected void generateStandardDeploymentDescriptor( JavaEEVersion javaEEVersion )
204         throws EarPluginException
205     {
206         File outputDir = new File( generatedDescriptorLocation );
207         if ( !outputDir.exists() )
208         {
209             outputDir.mkdirs();
210         }
211 
212         File descriptor = new File( outputDir, "application.xml" );
213 
214         final ApplicationXmlWriter writer = new ApplicationXmlWriter( javaEEVersion, encoding, generateModuleId );
215         final ApplicationXmlWriterContext context =
216             new ApplicationXmlWriterContext( descriptor, getModules(), buildSecurityRoles(), buildEnvEntries(),
217                                              displayName, description, getActualLibraryDirectory(), applicationName,
218                                              initializeInOrder ).setApplicationId( applicationId );
219         writer.write( context );
220     }
221 
222     /**
223      * Generates the jboss deployment descriptor.
224      */
225     protected void generateJbossDeploymentDescriptor()
226         throws EarPluginException
227     {
228         File outputDir = new File( generatedDescriptorLocation );
229         if ( !outputDir.exists() )
230         {
231             outputDir.mkdirs();
232         }
233 
234         File descriptor = new File( outputDir, "jboss-app.xml" );
235 
236         JbossAppXmlWriter writer = new JbossAppXmlWriter( encoding );
237         writer.write( descriptor, getJbossConfiguration(), getModules() );
238     }
239 
240     /**
241      * Builds the security roles based on the configuration.
242      * 
243      * @return a list of SecurityRole object(s)
244      * @throws EarPluginException if the configuration is invalid
245      */
246     private List<SecurityRole> buildSecurityRoles()
247         throws EarPluginException
248     {
249         final List<SecurityRole> result = new ArrayList<SecurityRole>();
250         if ( security == null )
251         {
252             return result;
253         }
254         try
255         {
256             final PlexusConfiguration[] securityRoles = security.getChildren( SecurityRole.SECURITY_ROLE );
257 
258             for ( PlexusConfiguration securityRole : securityRoles )
259             {
260                 final String id = securityRole.getAttribute( SecurityRole.ID_ATTRIBUTE );
261                 final String roleName = securityRole.getChild( SecurityRole.ROLE_NAME ).getValue();
262                 final String roleNameId =
263                     securityRole.getChild( SecurityRole.ROLE_NAME ).getAttribute( SecurityRole.ID_ATTRIBUTE );
264                 final String description = securityRole.getChild( SecurityRole.DESCRIPTION ).getValue();
265                 final String descriptionId =
266                     securityRole.getChild( SecurityRole.DESCRIPTION ).getAttribute( SecurityRole.ID_ATTRIBUTE );
267 
268                 if ( roleName == null )
269                 {
270                     throw new EarPluginException( "Invalid security-role configuration, role-name could not be null." );
271                 }
272                 else
273                 {
274                     result.add( new SecurityRole( roleName, roleNameId, id, description, descriptionId ) );
275                 }
276             }
277             return result;
278         }
279         catch ( PlexusConfigurationException e )
280         {
281             throw new EarPluginException( "Invalid security-role configuration", e );
282         }
283 
284     }
285 
286     /**
287      * Builds the env-entries based on the configuration.
288      * 
289      * @return a list of EnvEntry object(s)
290      * @throws EarPluginException if the configuration is invalid
291      */
292     private List<EnvEntry> buildEnvEntries()
293         throws EarPluginException
294     {
295         final List<EnvEntry> result = new ArrayList<EnvEntry>();
296         if ( envEntries == null )
297         {
298             return result;
299         }
300         try
301         {
302             final PlexusConfiguration[] allEnvEntries = envEntries.getChildren( EnvEntry.ENV_ENTRY );
303 
304             for ( PlexusConfiguration envEntry : allEnvEntries )
305             {
306                 final String description = envEntry.getChild( EnvEntry.DESCRIPTION ).getValue();
307                 final String envEntryName = envEntry.getChild( EnvEntry.ENV_ENTRY_NAME ).getValue();
308                 final String envEntryType = envEntry.getChild( EnvEntry.ENV_ENTRY_TYPE ).getValue();
309                 final String envEntryValue = envEntry.getChild( EnvEntry.ENV_ENTRY_VALUE ).getValue();
310 
311                 try
312                 {
313                     result.add( new EnvEntry( description, envEntryName, envEntryType, envEntryValue ) );
314                 }
315                 catch ( IllegalArgumentException e )
316                 {
317                     throw new EarPluginException( "Invalid env-entry [" + envEntry + "]", e );
318                 }
319             }
320             return result;
321         }
322         catch ( PlexusConfigurationException e )
323         {
324             throw new EarPluginException( "Invalid env-entry configuration", e );
325         }
326 
327     }
328 
329     /**
330      * Returns the value to use for the <tt>library-directory</tt> element, based on the library directory mode.
331      */
332     private String getActualLibraryDirectory()
333         throws EarPluginException
334     {
335         final String mode = libraryDirectoryMode == null ? DEFAULT : libraryDirectoryMode.toUpperCase();
336 
337         if ( DEFAULT.equals( mode ) )
338         {
339             return defaultLibBundleDir;
340         }
341         else if ( EMPTY.equals( mode ) )
342         {
343             return "";
344         }
345         else if ( NONE.equals( mode ) )
346         {
347             return null;
348         }
349         else
350         {
351             throw new EarPluginException( "Unsupported library directory mode [" + libraryDirectoryMode
352                 + "] Supported modes " + ( Arrays.asList( DEFAULT, EMPTY, NONE ) ) );
353         }
354     }
355 }