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