Coverage Report - org.apache.maven.plugin.ear.EarMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
EarMojo
0%
0/198
0%
0/108
5,211
 
 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.archiver.MavenArchiveConfiguration;
 23  
 import org.apache.maven.archiver.MavenArchiver;
 24  
 import org.apache.maven.execution.MavenSession;
 25  
 import org.apache.maven.plugin.MojoExecutionException;
 26  
 import org.apache.maven.plugin.MojoFailureException;
 27  
 import org.apache.maven.plugin.ear.util.EarMavenArchiver;
 28  
 import org.apache.maven.plugin.ear.util.JavaEEVersion;
 29  
 import org.apache.maven.project.MavenProjectHelper;
 30  
 import org.apache.maven.shared.filtering.MavenFileFilter;
 31  
 import org.apache.maven.shared.filtering.MavenFilteringException;
 32  
 import org.apache.maven.shared.filtering.MavenResourcesExecution;
 33  
 import org.apache.maven.shared.filtering.MavenResourcesFiltering;
 34  
 import org.codehaus.plexus.archiver.ArchiverException;
 35  
 import org.codehaus.plexus.archiver.UnArchiver;
 36  
 import org.codehaus.plexus.archiver.jar.JarArchiver;
 37  
 import org.codehaus.plexus.archiver.jar.Manifest;
 38  
 import org.codehaus.plexus.archiver.jar.Manifest.Attribute;
 39  
 import org.codehaus.plexus.archiver.jar.ManifestException;
 40  
 import org.codehaus.plexus.archiver.manager.ArchiverManager;
 41  
 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
 42  
 import org.codehaus.plexus.archiver.zip.ZipArchiver;
 43  
 import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
 44  
 import org.codehaus.plexus.util.DirectoryScanner;
 45  
 import org.codehaus.plexus.util.FileUtils;
 46  
 import org.codehaus.plexus.util.StringUtils;
 47  
 
 48  
 import java.io.File;
 49  
 import java.io.FileReader;
 50  
 import java.io.IOException;
 51  
 import java.io.PrintWriter;
 52  
 import java.util.ArrayList;
 53  
 import java.util.Arrays;
 54  
 import java.util.List;
 55  
 import java.util.zip.ZipException;
 56  
 
 57  
 /**
 58  
  * Builds J2EE Enterprise Archive (EAR) files.
 59  
  *
 60  
  * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
 61  
  * @version $Id: EarMojo.java 1228837 2012-01-08 13:19:38Z rfscholte $
 62  
  * @goal ear
 63  
  * @phase package
 64  
  * @threadSafe
 65  
  * @requiresDependencyResolution test
 66  
  */
 67  0
 public class EarMojo
 68  
     extends AbstractEarMojo
 69  
 {
 70  0
     private static final String[] EMPTY_STRING_ARRAY = { };
 71  
 
 72  
 
 73  
     /**
 74  
      * Single directory for extra files to include in the EAR.
 75  
      *
 76  
      * @parameter default-value="${basedir}/src/main/application"
 77  
      * @required
 78  
      */
 79  
     private File earSourceDirectory;
 80  
 
 81  
     /**
 82  
      * The comma separated list of tokens to include in the EAR.
 83  
      *
 84  
      * @parameter alias="includes" default-value="**"
 85  
      */
 86  
     private String earSourceIncludes;
 87  
 
 88  
     /**
 89  
      * The comma separated list of tokens to exclude from the EAR.
 90  
      *
 91  
      * @parameter alias="excludes"
 92  
      */
 93  
     private String earSourceExcludes;
 94  
 
 95  
     /**
 96  
      * Specify that the EAR sources should be filtered.
 97  
      *
 98  
      * @parameter default-value="false"
 99  
      * @since 2.3.2
 100  
      */
 101  
     private boolean filtering;
 102  
 
 103  
     /**
 104  
      * Filters (property files) to include during the interpolation of the pom.xml.
 105  
      *
 106  
      * @parameter
 107  
      * @since 2.3.2
 108  
      */
 109  
     private List filters;
 110  
 
 111  
     /**
 112  
      * A list of file extensions that should not be filtered if
 113  
      * filtering is enabled.
 114  
      *
 115  
      * @parameter
 116  
      * @since 2.3.2
 117  
      */
 118  
     private List nonFilteredFileExtensions;
 119  
 
 120  
     /**
 121  
      * To escape interpolated value with Windows path
 122  
      * c:\foo\bar will be replaced with c:\\foo\\bar.
 123  
      *
 124  
      * @parameter expression="${maven.ear.escapedBackslashesInFilePath}" default-value="false"
 125  
      * @since 2.3.2
 126  
      */
 127  
     private boolean escapedBackslashesInFilePath;
 128  
 
 129  
     /**
 130  
      * Expression preceded with this String won't be interpolated
 131  
      * \${foo} will be replaced with ${foo}.
 132  
      *
 133  
      * @parameter expression="${maven.ear.escapeString}"
 134  
      * @since 2.3.2
 135  
      */
 136  
     protected String escapeString;
 137  
 
 138  
     /**
 139  
      * The location of the manifest file to be used within the EAR file. If
 140  
      * no value if specified, the default location in the workDirectory is
 141  
      * taken. If the file does not exist, a manifest will be generated
 142  
      * automatically.
 143  
      *
 144  
      * @parameter
 145  
      */
 146  
     private File manifestFile;
 147  
 
 148  
     /**
 149  
      * The location of a custom application.xml file to be used
 150  
      * within the EAR file.
 151  
      *
 152  
      * @parameter
 153  
      */
 154  
     private String applicationXml;
 155  
 
 156  
     /**
 157  
      * The directory for the generated EAR.
 158  
      *
 159  
      * @parameter default-value="${project.build.directory}"
 160  
      * @required
 161  
      */
 162  
     private String outputDirectory;
 163  
 
 164  
     /**
 165  
      * The name of the EAR file to generate.
 166  
      *
 167  
      * @parameter alias="earName" default-value="${project.build.finalName}"
 168  
      * @required
 169  
      */
 170  
     private String finalName;
 171  
 
 172  
     /**
 173  
      * The comma separated list of artifact's type(s) to unpack
 174  
      * by default.
 175  
      *
 176  
      * @parameter
 177  
      */
 178  
     private String unpackTypes;
 179  
 
 180  
     /**
 181  
      * Classifier to add to the artifact generated. If given, the artifact will
 182  
      * be an attachment instead.
 183  
      *
 184  
      * @parameter
 185  
      */
 186  
     private String classifier;
 187  
 
 188  
     /**
 189  
      * A comma separated list of tokens to exclude when packaging the EAR.
 190  
      * By default nothing is excluded. Note that you can use the Java Regular
 191  
      * Expressions engine to include and exclude specific pattern using the
 192  
      * expression %regex[].
 193  
      * Hint: read the about (?!Pattern).
 194  
      *
 195  
      * @parameter
 196  
      * @since 2.7
 197  
      */
 198  
     private String packagingExcludes;
 199  
 
 200  
     /**
 201  
      * A comma separated list of tokens to include when packaging the EAR.
 202  
      * By default everything is included. Note that you can use the Java Regular
 203  
      * Expressions engine to include and exclude specific pattern using the
 204  
      * expression %regex[].
 205  
      *
 206  
      * @parameter
 207  
      * @since 2.7
 208  
      */
 209  
     private String packagingIncludes;
 210  
 
 211  
     /**
 212  
      * Whether to create skinny WARs or not. A skinny WAR is a WAR that does not
 213  
      * have all of its dependencies in WEB-INF/lib. Instead those dependencies
 214  
      * are shared between the WARs through the EAR.
 215  
      *
 216  
      * @parameter expression="${maven.ear.skinnyWars}" default-value="false"
 217  
      * @since 2.7
 218  
      */
 219  
     private boolean skinnyWars;
 220  
 
 221  
     /**
 222  
      * The Jar archiver.
 223  
      *
 224  
      * @component role="org.codehaus.plexus.archiver.Archiver" role-hint="jar"
 225  
      */
 226  
     private JarArchiver jarArchiver;
 227  
 
 228  
     /**
 229  
      * The Zip archiver.
 230  
      *
 231  
      * @component role="org.codehaus.plexus.archiver.Archiver" role-hint="zip"
 232  
      */
 233  
     private ZipArchiver zipArchiver;
 234  
 
 235  
     /**
 236  
      * The Zip Un archiver.
 237  
      *
 238  
      * @component role="org.codehaus.plexus.archiver.UnArchiver" role-hint="zip"
 239  
      */
 240  
     private ZipUnArchiver zipUnArchiver;
 241  
 
 242  
     /**
 243  
      * The archive configuration to use.
 244  
      * See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
 245  
      *
 246  
      * @parameter
 247  
      */
 248  0
     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
 249  
 
 250  
     /**
 251  
      * @component
 252  
      */
 253  
     private MavenProjectHelper projectHelper;
 254  
 
 255  
     /**
 256  
      * The archive manager.
 257  
      *
 258  
      * @component
 259  
      */
 260  
     private ArchiverManager archiverManager;
 261  
 
 262  
     /**
 263  
      * @component role="org.apache.maven.shared.filtering.MavenFileFilter" role-hint="default"
 264  
      * @required
 265  
      */
 266  
     private MavenFileFilter mavenFileFilter;
 267  
 
 268  
     /**
 269  
      * @component role="org.apache.maven.shared.filtering.MavenResourcesFiltering" role-hint="default"
 270  
      * @required
 271  
      */
 272  
     private MavenResourcesFiltering mavenResourcesFiltering;
 273  
 
 274  
     /**
 275  
      * @parameter expression="${session}"
 276  
      * @readonly
 277  
      * @required
 278  
      * @since 2.3.2
 279  
      */
 280  
     private MavenSession session;
 281  
 
 282  
 
 283  
     private List filterWrappers;
 284  
 
 285  
 
 286  
     public void execute()
 287  
         throws MojoExecutionException, MojoFailureException
 288  
     {
 289  
         // Initializes ear modules
 290  0
         super.execute();
 291  
 
 292  0
         final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );
 293  
 
 294  
         // Initializes unpack types
 295  0
         List<String> unpackTypesList = new ArrayList<String>();
 296  0
         if ( unpackTypes != null )
 297  
         {
 298  0
             unpackTypesList = Arrays.asList( unpackTypes.split( "," ) );
 299  0
             for ( String type : unpackTypesList )
 300  
             {
 301  0
                 if ( !EarModuleFactory.standardArtifactTypes.contains( type ) )
 302  
                 {
 303  0
                     throw new MojoExecutionException(
 304  
                         "Invalid type [" + type + "] supported types are " + EarModuleFactory.standardArtifactTypes );
 305  
                 }
 306  
             }
 307  0
             getLog().debug( "Initialized unpack types " + unpackTypesList );
 308  
         }
 309  
 
 310  
         // Copy modules
 311  
         try
 312  
         {
 313  0
             for ( EarModule module: getModules() )
 314  
             {
 315  0
                 if ( module instanceof JavaModule )
 316  
                 {
 317  0
                     getLog().warn( "JavaModule is deprecated (" + module + "), please use JarModule instead." );
 318  
                 }
 319  0
                 if ( module instanceof Ejb3Module )
 320  
                 {
 321  0
                     getLog().warn( "Ejb3Module is deprecated (" + module + "), please use EjbModule instead." );
 322  
                 }
 323  0
                 final File sourceFile = module.getArtifact().getFile();
 324  0
                 final File destinationFile = buildDestinationFile( getWorkDirectory(), module.getUri() );
 325  0
                 if ( !sourceFile.isFile() )
 326  
                 {
 327  0
                     throw new MojoExecutionException(
 328  
                         "Cannot copy a directory: " + sourceFile.getAbsolutePath() + "; Did you package/install "
 329  
                             + module.getArtifact() + "?" );
 330  
                 }
 331  
 
 332  0
                 if ( destinationFile.getCanonicalPath().equals( sourceFile.getCanonicalPath() ) )
 333  
                 {
 334  0
                     getLog().info(
 335  
                         "Skipping artifact [" + module + "], as it already exists at [" + module.getUri() + "]" );
 336  0
                     continue;
 337  
                 }
 338  
 
 339  
                 // If the module is within the unpack list, make sure that no unpack wasn't forced (null or true)
 340  
                 // If the module is not in the unpack list, it should be true
 341  0
                 if ( ( unpackTypesList.contains( module.getType() )
 342  
                     && ( module.shouldUnpack() == null || module.shouldUnpack().booleanValue() ) )
 343  
                     || ( module.shouldUnpack() != null && module.shouldUnpack().booleanValue() ) )
 344  
                 {
 345  0
                     getLog().info( "Copying artifact [" + module + "] to [" + module.getUri() + "] (unpacked)" );
 346  
                     // Make sure that the destination is a directory to avoid plexus nasty stuff :)
 347  0
                     destinationFile.mkdirs();
 348  0
                     unpack( sourceFile, destinationFile );
 349  
 
 350  0
                     if ( skinnyWars && module.changeManifestClasspath() )
 351  
                     {
 352  0
                         changeManifestClasspath( module, destinationFile );
 353  
                     }
 354  
                 }
 355  
                 else
 356  
                 {
 357  0
                     if ( sourceFile.lastModified() > destinationFile.lastModified() )
 358  
                     {
 359  0
                         getLog().info( "Copying artifact [" + module + "] to [" + module.getUri() + "]" );
 360  0
                         FileUtils.copyFile( sourceFile, destinationFile );
 361  
 
 362  0
                         if ( skinnyWars && module.changeManifestClasspath() )
 363  
                         {
 364  0
                             changeManifestClasspath( module, destinationFile );
 365  
                         }
 366  
                     }
 367  
                     else
 368  
                     {
 369  0
                         getLog().debug(
 370  
                             "Skipping artifact [" + module + "], as it is already up to date at [" + module.getUri()
 371  
                                 + "]" );
 372  
                     }
 373  
                 }
 374  0
             }
 375  
         }
 376  0
         catch ( IOException e )
 377  
         {
 378  0
             throw new MojoExecutionException( "Error copying EAR modules", e );
 379  
         }
 380  0
         catch ( ArchiverException e )
 381  
         {
 382  0
             throw new MojoExecutionException( "Error unpacking EAR modules", e );
 383  
         }
 384  0
         catch ( NoSuchArchiverException e )
 385  
         {
 386  0
             throw new MojoExecutionException( "No Archiver found for EAR modules", e );
 387  0
         }
 388  
 
 389  
         // Copy source files
 390  
         try
 391  
         {
 392  0
             File earSourceDir = earSourceDirectory;
 393  0
             if ( earSourceDir.exists() )
 394  
             {
 395  0
                 getLog().info( "Copy ear sources to " + getWorkDirectory().getAbsolutePath() );
 396  0
                 String[] fileNames = getEarFiles( earSourceDir );
 397  0
                 for ( int i = 0; i < fileNames.length; i++ )
 398  
                 {
 399  0
                     copyFile( new File( earSourceDir, fileNames[i] ), new File( getWorkDirectory(), fileNames[i] ) );
 400  
                 }
 401  
             }
 402  
 
 403  0
             if ( applicationXml != null && !"".equals( applicationXml ) )
 404  
             {
 405  
                 //rename to application.xml
 406  0
                 getLog().info( "Including custom application.xml[" + applicationXml + "]" );
 407  0
                 File metaInfDir = new File( getWorkDirectory(), META_INF );
 408  0
                 copyFile( new File( applicationXml ), new File( metaInfDir, "/application.xml" ) );
 409  
             }
 410  
 
 411  
         }
 412  0
         catch ( IOException e )
 413  
         {
 414  0
             throw new MojoExecutionException( "Error copying EAR sources", e );
 415  
         }
 416  0
         catch ( MavenFilteringException e )
 417  
         {
 418  0
             throw new MojoExecutionException( "Error filtering EAR sources", e );
 419  0
         }
 420  
 
 421  
         // Check if deployment descriptor is there
 422  0
         File ddFile = new File( getWorkDirectory(), APPLICATION_XML_URI );
 423  0
         if ( !ddFile.exists() && ( javaEEVersion.lt( JavaEEVersion.Five ) ) )
 424  
         {
 425  0
             throw new MojoExecutionException(
 426  
                 "Deployment descriptor: " + ddFile.getAbsolutePath() + " does not exist." );
 427  
         }
 428  
 
 429  
         try
 430  
         {
 431  0
             File earFile = getEarFile( outputDirectory, finalName, classifier );
 432  0
             final MavenArchiver archiver = new EarMavenArchiver( getModules() );
 433  0
             final JarArchiver jarArchiver = getJarArchiver();
 434  0
             getLog().debug( "Jar archiver implementation [" + jarArchiver.getClass().getName() + "]" );
 435  0
             archiver.setArchiver( jarArchiver );
 436  0
             archiver.setOutputFile( earFile );
 437  
 
 438  
             // Include custom manifest if necessary
 439  0
             includeCustomManifestFile();
 440  
 
 441  0
             getLog().debug(
 442  
                 "Excluding " + Arrays.asList( getPackagingExcludes() ) + " from the generated EAR." );
 443  0
             getLog().debug(
 444  
                 "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated EAR." );
 445  
 
 446  0
             archiver.getArchiver().addDirectory( getWorkDirectory(), getPackagingIncludes(), getPackagingExcludes() );
 447  0
             archiver.createArchive( getProject(), archive );
 448  
 
 449  0
             if ( classifier != null )
 450  
             {
 451  0
                 projectHelper.attachArtifact( getProject(), "ear", classifier, earFile );
 452  
             }
 453  
             else
 454  
             {
 455  0
                 getProject().getArtifact().setFile( earFile );
 456  
             }
 457  
         }
 458  0
         catch ( Exception e )
 459  
         {
 460  0
             throw new MojoExecutionException( "Error assembling EAR", e );
 461  0
         }
 462  0
     }
 463  
 
 464  
     public String getApplicationXml()
 465  
     {
 466  0
         return applicationXml;
 467  
     }
 468  
 
 469  
     public void setApplicationXml( String applicationXml )
 470  
     {
 471  0
         this.applicationXml = applicationXml;
 472  0
     }
 473  
 
 474  
     /**
 475  
      * Returns a string array of the excludes to be used
 476  
      * when assembling/copying the ear.
 477  
      *
 478  
      * @return an array of tokens to exclude
 479  
      */
 480  
     protected String[] getExcludes()
 481  
     {
 482  
         @SuppressWarnings( "unchecked" )
 483  0
         List<String> excludeList = new ArrayList<String>( FileUtils.getDefaultExcludesAsList() );
 484  0
         if ( earSourceExcludes != null && !"".equals( earSourceExcludes ) )
 485  
         {
 486  0
             excludeList.addAll( Arrays.asList( StringUtils.split( earSourceExcludes, "," ) ) );
 487  
         }
 488  
 
 489  
         // if applicationXml is specified, omit the one in the source directory
 490  0
         if ( getApplicationXml() != null && !"".equals( getApplicationXml() ) )
 491  
         {
 492  0
             excludeList.add( "**/" + META_INF + "/application.xml" );
 493  
         }
 494  
 
 495  0
         return (String[]) excludeList.toArray( EMPTY_STRING_ARRAY );
 496  
     }
 497  
 
 498  
     /**
 499  
      * Returns a string array of the includes to be used
 500  
      * when assembling/copying the ear.
 501  
      *
 502  
      * @return an array of tokens to include
 503  
      */
 504  
     protected String[] getIncludes()
 505  
     {
 506  0
         return StringUtils.split( StringUtils.defaultString( earSourceIncludes ), "," );
 507  
     }
 508  
 
 509  
     public String[] getPackagingExcludes()
 510  
     {
 511  0
         if ( StringUtils.isEmpty( packagingExcludes ) )
 512  
         {
 513  0
             return new String[0];
 514  
         }
 515  
         else
 516  
         {
 517  0
             return StringUtils.split( packagingExcludes, "," );
 518  
         }
 519  
     }
 520  
 
 521  
     public void setPackagingExcludes( String packagingExcludes )
 522  
     {
 523  0
         this.packagingExcludes = packagingExcludes;
 524  0
     }
 525  
 
 526  
     public String[] getPackagingIncludes()
 527  
     {
 528  0
         if ( StringUtils.isEmpty( packagingIncludes ) )
 529  
         {
 530  0
             return new String[]{"**"};
 531  
         }
 532  
         else
 533  
         {
 534  0
             return StringUtils.split( packagingIncludes, "," );
 535  
         }
 536  
     }
 537  
 
 538  
     public void setPackagingIncludes( String packagingIncludes )
 539  
     {
 540  0
         this.packagingIncludes = packagingIncludes;
 541  0
     }
 542  
 
 543  
     private static File buildDestinationFile( File buildDir, String uri )
 544  
     {
 545  0
         return new File( buildDir, uri );
 546  
     }
 547  
 
 548  
     private void includeCustomManifestFile()
 549  
     {
 550  0
         if ( manifestFile == null )
 551  
         {
 552  0
             manifestFile = new File( getWorkDirectory(), "META-INF/MANIFEST.MF" );
 553  
         }
 554  
 
 555  0
         if ( !manifestFile.exists() )
 556  
         {
 557  0
             getLog().info( "Could not find manifest file: " + manifestFile + " - Generating one" );
 558  
         }
 559  
         else
 560  
         {
 561  0
             getLog().info( "Including custom manifest file [" + manifestFile + "]" );
 562  0
             archive.setManifestFile( manifestFile );
 563  
         }
 564  0
     }
 565  
 
 566  
     /**
 567  
      * Returns the EAR file to generate, based on an optional classifier.
 568  
      *
 569  
      * @param basedir    the output directory
 570  
      * @param finalName  the name of the ear file
 571  
      * @param classifier an optional classifier
 572  
      * @return the EAR file to generate
 573  
      */
 574  
     private static File getEarFile( String basedir, String finalName, String classifier )
 575  
     {
 576  0
         if ( classifier == null )
 577  
         {
 578  0
             classifier = "";
 579  
         }
 580  0
         else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
 581  
         {
 582  0
             classifier = "-" + classifier;
 583  
         }
 584  
 
 585  0
         return new File( basedir, finalName + classifier + ".ear" );
 586  
     }
 587  
 
 588  
     /**
 589  
      * Returns a list of filenames that should be copied
 590  
      * over to the destination directory.
 591  
      *
 592  
      * @param sourceDir the directory to be scanned
 593  
      * @return the array of filenames, relative to the sourceDir
 594  
      */
 595  
     private String[] getEarFiles( File sourceDir )
 596  
     {
 597  0
         DirectoryScanner scanner = new DirectoryScanner();
 598  0
         scanner.setBasedir( sourceDir );
 599  0
         scanner.setExcludes( getExcludes() );
 600  0
         scanner.addDefaultExcludes();
 601  
 
 602  0
         scanner.setIncludes( getIncludes() );
 603  
 
 604  0
         scanner.scan();
 605  
 
 606  0
         return scanner.getIncludedFiles();
 607  
     }
 608  
 
 609  
     /**
 610  
      * Unpacks the module into the EAR structure.
 611  
      *
 612  
      * @param source  File to be unpacked.
 613  
      * @param destDir Location where to put the unpacked files.
 614  
      */
 615  
     public void unpack( File source, File destDir )
 616  
         throws NoSuchArchiverException, IOException, ArchiverException
 617  
     {
 618  0
         UnArchiver unArchiver = archiverManager.getUnArchiver( "zip" );
 619  0
         unArchiver.setSourceFile( source );
 620  0
         unArchiver.setDestDirectory( destDir );
 621  
 
 622  
         // Extract the module
 623  0
         unArchiver.extract();
 624  0
     }
 625  
 
 626  
     /**
 627  
      * Returns the {@link JarArchiver} implementation used
 628  
      * to package the EAR file.
 629  
      * <p/>
 630  
      * By default the archiver is obtained from the Plexus container.
 631  
      *
 632  
      * @return the archiver
 633  
      */
 634  
     protected JarArchiver getJarArchiver()
 635  
     {
 636  0
         return jarArchiver;
 637  
     }
 638  
 
 639  
     private void copyFile( File source, File target )
 640  
         throws MavenFilteringException, IOException, MojoExecutionException
 641  
     {
 642  0
         if ( filtering && !isNonFilteredExtension( source.getName() ) )
 643  
         {
 644  
             // Silly that we have to do this ourselves
 645  0
             if ( target.getParentFile() != null && !target.getParentFile().exists() )
 646  
             {
 647  0
                 target.getParentFile().mkdirs();
 648  
             }
 649  0
             mavenFileFilter.copyFile( source, target, true, getFilterWrappers(), null );
 650  
         }
 651  
         else
 652  
         {
 653  0
             FileUtils.copyFile( source, target );
 654  
         }
 655  0
     }
 656  
 
 657  
     public boolean isNonFilteredExtension( String fileName )
 658  
     {
 659  0
         return !mavenResourcesFiltering.filteredFileExtension( fileName, nonFilteredFileExtensions );
 660  
     }
 661  
 
 662  
     private List getFilterWrappers()
 663  
         throws MojoExecutionException
 664  
     {
 665  0
         if ( filterWrappers == null )
 666  
         {
 667  
             try
 668  
             {
 669  0
                 MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
 670  0
                 mavenResourcesExecution.setEscapeString( escapeString );
 671  0
                 filterWrappers =
 672  
                     mavenFileFilter.getDefaultFilterWrappers( project, filters, escapedBackslashesInFilePath,
 673  
                                                               this.session, mavenResourcesExecution );
 674  
             }
 675  0
             catch ( MavenFilteringException e )
 676  
             {
 677  0
                 getLog().error( "Fail to build filtering wrappers " + e.getMessage() );
 678  0
                 throw new MojoExecutionException( e.getMessage(), e );
 679  0
             }
 680  
         }
 681  0
         return filterWrappers;
 682  
     }
 683  
 
 684  
     private void changeManifestClasspath( EarModule module, File original )
 685  
             throws MojoFailureException
 686  
     {
 687  
         try
 688  
         {
 689  
             File workDirectory;
 690  
 
 691  
             // Handle the case that the destination might be a directory (project-038)
 692  0
             if ( original.isFile() )
 693  
             {
 694  
                 // Create a temporary work directory
 695  0
                 workDirectory = new File( new File(
 696  
                         generatedDescriptorLocation, "temp" ), module.getArtifact()
 697  
                         .getArtifactId() );
 698  0
                 workDirectory.mkdirs();
 699  0
                 getLog().debug( "Created a temporary work directory: " + workDirectory.getAbsolutePath() );
 700  
 
 701  
                 // Unpack the archive to a temporary work directory
 702  0
                 zipUnArchiver.setSourceFile( original );
 703  0
                 zipUnArchiver.setDestDirectory( workDirectory );
 704  0
                 zipUnArchiver.extract();
 705  
             }
 706  
             else
 707  
             {
 708  0
                 workDirectory = original;
 709  
             }
 710  
 
 711  
             // Create a META-INF/MANIFEST.MF file if it doesn't exist (project-038)
 712  0
             File metaInfDirectory = new File( workDirectory, "META-INF" );
 713  0
             boolean newMetaInfCreated = metaInfDirectory.mkdirs();
 714  0
             if ( newMetaInfCreated )
 715  
             {
 716  0
                 getLog().debug(
 717  
                         "This project did not have a META-INF directory before, so a new directory was created." );
 718  
             }
 719  0
             File manifestFile = new File( metaInfDirectory, "MANIFEST.MF" );
 720  0
             boolean newManifestCreated = manifestFile.createNewFile();
 721  0
             if ( newManifestCreated )
 722  
             {
 723  0
                 getLog().debug(
 724  
                         "This project did not have a META-INF/MANIFEST.MF file before, so a new file was created." );
 725  
             }
 726  
 
 727  
             // Read the manifest from disk
 728  0
             Manifest mf = new Manifest( new FileReader( manifestFile ) );
 729  0
             Attribute classPath = mf.getMainSection()
 730  
                     .getAttribute( "Class-Path" );
 731  0
             List<String> classPathElements = new ArrayList<String>();
 732  
 
 733  0
             if ( classPath != null )
 734  
             {
 735  0
                 classPathElements.addAll( Arrays.asList( classPath.getValue()
 736  
                         .split( " " ) ) );
 737  
             }
 738  
             else
 739  
             {
 740  0
                 classPath = new Attribute( "Class-Path", "" );
 741  0
                 mf.getMainSection().addConfiguredAttribute( classPath );
 742  
             }
 743  
 
 744  
             // Modify the classpath entries in the manifest
 745  0
             for ( EarModule o : getModules() )
 746  
             {
 747  0
                 if ( o instanceof JarModule )
 748  
                 {
 749  0
                     JarModule jm = ( JarModule ) o;
 750  
 
 751  0
                     if ( module.getLibDir() != null )
 752  
                     {
 753  0
                         File artifact = new File( new File(
 754  
                                 workDirectory, module.getLibDir() ),
 755  
                                 jm.getBundleFileName() );
 756  
 
 757  0
                         if ( artifact.exists() )
 758  
                         {
 759  0
                             if ( !artifact.delete() )
 760  
                             {
 761  0
                                 getLog().error(
 762  
                                         "Could not delete '" + artifact + "'" );
 763  
                             }
 764  
                         }
 765  
                     }
 766  
 
 767  0
                     if ( classPathElements.contains( jm.getBundleFileName() ) )
 768  
                     {
 769  0
                         classPathElements.set( classPathElements.indexOf( jm
 770  
                                 .getBundleFileName() ), jm.getUri() );
 771  
                     }
 772  
                     else
 773  
                     {
 774  0
                         classPathElements.add( jm.getUri() );
 775  
                     }
 776  0
                 }
 777  
             }
 778  0
             classPath.setValue( StringUtils.join( classPathElements.iterator(), " " ) );
 779  
 
 780  
             // Write the manifest to disk
 781  0
             PrintWriter pw = new PrintWriter( manifestFile );
 782  0
             mf.write( pw );
 783  0
             pw.close();
 784  
 
 785  0
             if ( original.isFile() )
 786  
             {
 787  
                 // Pack up the archive again from the work directory
 788  0
                 if ( !original.delete() )
 789  
                 {
 790  0
                     getLog().error( "Could not delete original artifact file " + original );
 791  
                 }
 792  
 
 793  0
                 getLog().debug( "Zipping module" );
 794  0
                 zipArchiver.setDestFile( original );
 795  0
                 zipArchiver.addDirectory( workDirectory );
 796  0
                 zipArchiver.createArchive();
 797  
             }
 798  
         }
 799  0
         catch ( ManifestException e )
 800  
         {
 801  0
             throw new MojoFailureException( e.getMessage() );
 802  
         }
 803  0
         catch ( ZipException e )
 804  
         {
 805  0
             throw new MojoFailureException( e.getMessage() );
 806  
         }
 807  0
         catch ( IOException e )
 808  
         {
 809  0
             throw new MojoFailureException( e.getMessage() );
 810  
         }
 811  0
         catch ( ArchiverException e )
 812  
         {
 813  0
             throw new MojoFailureException( e.getMessage() );
 814  0
         }
 815  0
     }
 816  
 }