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 java.io.File;
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.Set;
26  
27  import org.apache.maven.artifact.Artifact;
28  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
29  import org.apache.maven.plugin.AbstractMojo;
30  import org.apache.maven.plugin.MojoExecutionException;
31  import org.apache.maven.plugin.MojoFailureException;
32  import org.apache.maven.plugin.ear.util.ArtifactTypeMappingService;
33  import org.apache.maven.plugin.ear.util.JavaEEVersion;
34  import org.apache.maven.plugins.annotations.Parameter;
35  import org.apache.maven.project.MavenProject;
36  import org.codehaus.plexus.configuration.PlexusConfiguration;
37  import org.codehaus.plexus.configuration.PlexusConfigurationException;
38  
39  /**
40   * A base class for EAR-processing related tasks.
41   * 
42   * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
43   * @version $Id: AbstractEarMojo.java 1542511 2013-11-16 13:33:56Z rfscholte $
44   */
45  public abstract class AbstractEarMojo
46      extends AbstractMojo
47  {
48      public static final String APPLICATION_XML_URI = "META-INF/application.xml";
49  
50      public static final String META_INF = "META-INF";
51  
52      public static final String UTF_8 = "UTF-8";
53  
54      /**
55       * The version of the application.xml to generate. Valid values are 1.3, 1.4, 5, 6 and 7.
56       */
57      @Parameter( defaultValue = "1.3" )
58      protected String version;
59  
60      /**
61       * Character encoding for the auto-generated deployment file(s).
62       */
63      @Parameter( defaultValue = "UTF-8" )
64      protected String encoding;
65  
66      /**
67       * Directory where the deployment descriptor file(s) will be auto-generated.
68       */
69      @Parameter( defaultValue = "${project.build.directory}" )
70      protected String generatedDescriptorLocation;
71  
72      /**
73       * The maven project.
74       */
75      @Parameter( defaultValue = "${project}", readonly = true, required = true )
76      protected MavenProject project;
77  
78      /**
79       * The ear modules configuration.
80       */
81      @Parameter
82      private EarModule[] modules;
83  
84      /**
85       * The artifact type mappings.
86       */
87      @Parameter
88      protected PlexusConfiguration artifactTypeMappings;
89  
90      /**
91       * The default bundle dir for libraries.
92       */
93      @Parameter( alias = "defaultJavaBundleDir" )
94      protected String defaultLibBundleDir;
95  
96      /**
97       * Should libraries be added in application.xml
98       */
99      @Parameter( defaultValue = "false" )
100     private Boolean includeLibInApplicationXml = Boolean.FALSE;
101 
102     /**
103      * The file name mapping to use for all dependencies included in the EAR file.
104      */
105     @Parameter
106     private String fileNameMapping;
107 
108     /**
109      * When using a {@link #fileNameMapping} with versions, either use the {@code baseVersion} or the {@code version}.
110      * When the artifact is a SNAPSHOT, {@code version} will always return a value with a {@code -SNAPSHOT} postfix
111      * instead of the possible timestamped value.
112      * 
113      * @since 2.9
114      */
115     @Parameter
116     private Boolean useBaseVersion;
117 
118     /**
119      * Directory that resources are copied to during the build.
120      */
121     @Parameter( defaultValue = "${project.build.directory}/${project.build.finalName}", required = true )
122     private File workDirectory;
123 
124     /**
125      * The JBoss specific configuration.
126      * 
127      * @parameter
128      */
129     @Parameter
130     private PlexusConfiguration jboss;
131 
132     /**
133      * The id to use to define the main artifact (e.g. the artifact without a classifier) when there is multiple
134      * candidates.
135      * 
136      * @parameter
137      */
138     @Parameter
139     private String mainArtifactId = "none";
140 
141     private List<EarModule> earModules;
142 
143     private List<EarModule> allModules;
144 
145     private JbossConfiguration jbossConfiguration;
146 
147     @SuppressWarnings( "unchecked" )
148     public void execute()
149         throws MojoExecutionException, MojoFailureException
150     {
151         final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );
152         getLog().debug( "Resolving artifact type mappings ..." );
153         ArtifactTypeMappingService typeMappingService;
154         try
155         {
156             typeMappingService = new ArtifactTypeMappingService();
157             typeMappingService.configure( artifactTypeMappings );
158         }
159         catch ( EarPluginException e )
160         {
161             throw new MojoExecutionException( "Failed to initialize artifact type mappings", e );
162         }
163         catch ( PlexusConfigurationException e )
164         {
165             throw new MojoExecutionException( "Invalid artifact type mappings configuration", e );
166         }
167 
168         getLog().debug( "Initializing JBoss configuration if necessary ..." );
169         try
170         {
171             initializeJbossConfiguration();
172         }
173         catch ( EarPluginException e )
174         {
175             throw new MojoExecutionException( "Failed to initialize JBoss configuration", e );
176         }
177 
178         getLog().debug( "Initializing ear execution context" );
179         EarExecutionContext earExecutionContext =
180             new EarExecutionContext( project, mainArtifactId, defaultLibBundleDir, jbossConfiguration, fileNameMapping,
181                                      typeMappingService );
182 
183         if ( useBaseVersion != null )
184         {
185             earExecutionContext.getFileNameMapping().setUseBaseVersion( useBaseVersion );
186         }
187 
188         getLog().debug( "Resolving ear modules ..." );
189         allModules = new ArrayList<EarModule>();
190         try
191         {
192             if ( modules != null && modules.length > 0 )
193             {
194                 // Let's validate user-defined modules
195                 EarModule module;
196 
197                 for ( EarModule module1 : modules )
198                 {
199                     module = module1;
200                     getLog().debug( "Resolving ear module[" + module + "]" );
201                     module.setEarExecutionContext( earExecutionContext );
202                     module.resolveArtifact( project.getArtifacts() );
203                     allModules.add( module );
204                 }
205             }
206 
207             // Let's add other modules
208             Set<Artifact> artifacts = project.getArtifacts();
209             for ( Artifact artifact : artifacts )
210             {
211                 // If the artifact's type is POM, ignore and continue
212                 // since it's used for transitive deps only.
213                 if ( "pom".equals( artifact.getType() ) )
214                 {
215                     continue;
216                 }
217 
218                 // Artifact is not yet registered and it has neither test, nor a
219                 // provided scope, not is it optional
220                 ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
221                 if ( !isArtifactRegistered( artifact, allModules ) && !artifact.isOptional()
222                     && filter.include( artifact ) )
223                 {
224                     EarModule module =
225                         EarModuleFactory.newEarModule( artifact, javaEEVersion, defaultLibBundleDir,
226                                                        includeLibInApplicationXml, typeMappingService );
227                     module.setEarExecutionContext( earExecutionContext );
228                     allModules.add( module );
229                 }
230             }
231         }
232         catch ( EarPluginException e )
233         {
234             throw new MojoExecutionException( "Failed to initialize ear modules", e );
235         }
236 
237         // Now we have everything let's built modules which have not been excluded
238         earModules = new ArrayList<EarModule>();
239         for ( EarModule earModule : allModules )
240         {
241             if ( earModule.isExcluded() )
242             {
243                 getLog().debug( "Skipping ear module[" + earModule + "]" );
244             }
245             else
246             {
247                 earModules.add( earModule );
248             }
249         }
250 
251     }
252 
253     protected List<EarModule> getModules()
254     {
255         if ( earModules == null )
256         {
257             throw new IllegalStateException( "Ear modules have not been initialized" );
258         }
259         return earModules;
260     }
261 
262     protected MavenProject getProject()
263     {
264         return project;
265     }
266 
267     protected File getWorkDirectory()
268     {
269         return workDirectory;
270     }
271 
272     protected JbossConfiguration getJbossConfiguration()
273     {
274         return jbossConfiguration;
275     }
276 
277     private static boolean isArtifactRegistered( Artifact a, List<EarModule> currentList )
278     {
279         for ( EarModule em : currentList )
280         {
281             if ( em.getArtifact().equals( a ) )
282             {
283                 return true;
284             }
285         }
286         return false;
287     }
288 
289     /**
290      * Initializes the JBoss configuration.
291      * 
292      * @throws EarPluginException if the configuration is invalid
293      */
294     private void initializeJbossConfiguration()
295         throws EarPluginException
296     {
297         if ( jboss == null )
298         {
299             jbossConfiguration = null;
300         }
301         else
302         {
303             try
304             {
305                 String version = jboss.getChild( JbossConfiguration.VERSION ).getValue();
306                 if ( version == null )
307                 {
308                     getLog().info( "JBoss version not set, using JBoss 4 by default" );
309                     version = JbossConfiguration.VERSION_4;
310                 }
311                 final String securityDomain = jboss.getChild( JbossConfiguration.SECURITY_DOMAIN ).getValue();
312                 final String unauthenticatedPrincipal =
313                     jboss.getChild( JbossConfiguration.UNAUHTHENTICTED_PRINCIPAL ).getValue();
314 
315                 final PlexusConfiguration loaderRepositoryEl = jboss.getChild( JbossConfiguration.LOADER_REPOSITORY );
316                 final String loaderRepository = loaderRepositoryEl.getValue();
317                 final String loaderRepositoryClass =
318                     loaderRepositoryEl.getAttribute( JbossConfiguration.LOADER_REPOSITORY_CLASS_ATTRIBUTE );
319                 final PlexusConfiguration loaderRepositoryConfigEl =
320                     jboss.getChild( JbossConfiguration.LOADER_REPOSITORY_CONFIG );
321                 final String loaderRepositoryConfig = loaderRepositoryConfigEl.getValue();
322                 final String configParserClass =
323                     loaderRepositoryConfigEl.getAttribute( JbossConfiguration.CONFIG_PARSER_CLASS_ATTRIBUTE );
324 
325                 final String jmxName = jboss.getChild( JbossConfiguration.JMX_NAME ).getValue();
326                 final String moduleOrder = jboss.getChild( JbossConfiguration.MODULE_ORDER ).getValue();
327 
328                 final List<String> dataSources = new ArrayList<String>();
329                 final PlexusConfiguration dataSourcesEl = jboss.getChild( JbossConfiguration.DATASOURCES );
330                 if ( dataSourcesEl != null )
331                 {
332 
333                     final PlexusConfiguration[] dataSourcesConfig =
334                         dataSourcesEl.getChildren( JbossConfiguration.DATASOURCE );
335                     for ( PlexusConfiguration dataSourceConfig : dataSourcesConfig )
336                     {
337                         dataSources.add( dataSourceConfig.getValue() );
338 
339                     }
340                 }
341                 final String libraryDirectory = jboss.getChild( JbossConfiguration.LIBRARY_DIRECTORY ).getValue();
342                 jbossConfiguration =
343                     new JbossConfiguration( version, securityDomain, unauthenticatedPrincipal, jmxName,
344                                             loaderRepository, moduleOrder, dataSources, libraryDirectory,
345                                             loaderRepositoryConfig, loaderRepositoryClass, configParserClass );
346             }
347             catch ( PlexusConfigurationException e )
348             {
349                 throw new EarPluginException( "Invalid JBoss configuration", e );
350             }
351         }
352     }
353 }