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