Coverage Report - org.apache.maven.plugin.war.WarMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
WarMojo
69%
68/98
70%
21/30
1,926
 
 1  
 package org.apache.maven.plugin.war;
 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.MavenArchiver;
 23  
 import org.apache.maven.artifact.Artifact;
 24  
 import org.apache.maven.artifact.DependencyResolutionRequiredException;
 25  
 import org.apache.maven.plugin.MojoExecutionException;
 26  
 import org.apache.maven.plugin.MojoFailureException;
 27  
 import org.apache.maven.plugin.war.util.ClassesPackager;
 28  
 import org.apache.maven.plugins.annotations.Component;
 29  
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 30  
 import org.apache.maven.plugins.annotations.Mojo;
 31  
 import org.apache.maven.plugins.annotations.Parameter;
 32  
 import org.apache.maven.plugins.annotations.ResolutionScope;
 33  
 import org.apache.maven.project.MavenProjectHelper;
 34  
 import org.codehaus.plexus.archiver.Archiver;
 35  
 import org.codehaus.plexus.archiver.ArchiverException;
 36  
 import org.codehaus.plexus.archiver.jar.ManifestException;
 37  
 import org.codehaus.plexus.archiver.war.WarArchiver;
 38  
 import org.codehaus.plexus.util.FileUtils;
 39  
 import org.codehaus.plexus.util.StringUtils;
 40  
 
 41  
 import java.io.File;
 42  
 import java.io.IOException;
 43  
 import java.util.Arrays;
 44  
 
 45  
 /**
 46  
  * Build a WAR file.
 47  
  *
 48  
  * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
 49  
  * @version $Id: WarMojo.java 1391186 2012-09-27 19:36:49Z krosenvold $
 50  
  */
 51  
 @Mojo( name = "war", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true,
 52  
        requiresDependencyResolution = ResolutionScope.RUNTIME )
 53  34
 public class WarMojo
 54  
     extends AbstractWarMojo
 55  
 {
 56  
     /**
 57  
      * The directory for the generated WAR.
 58  
      */
 59  
     @Parameter( defaultValue = "${project.build.directory}", required = true )
 60  
     private String outputDirectory;
 61  
 
 62  
     /**
 63  
      * The name of the generated WAR.
 64  
      */
 65  
     @Parameter( defaultValue = "${project.build.finalName}", required = true )
 66  
     private String warName;
 67  
 
 68  
     /**
 69  
      * Classifier to add to the generated WAR. If given, the artifact will be an attachment instead.
 70  
      * The classifier will not be applied to the JAR file of the project - only to the WAR file.
 71  
      */
 72  
     @Parameter
 73  
     private String classifier;
 74  
 
 75  
     /**
 76  
      * The comma separated list of tokens to exclude from the WAR before
 77  
      * packaging. This option may be used to implement the skinny WAR use
 78  
      * case. Note that you can use the Java Regular Expressions engine to
 79  
      * include and exclude specific pattern using the expression %regex[].
 80  
      * Hint: read the about (?!Pattern).
 81  
      *
 82  
      * @since 2.1-alpha-2
 83  
      */
 84  
     @Parameter
 85  
     private String packagingExcludes;
 86  
 
 87  
     /**
 88  
      * The comma separated list of tokens to include in the WAR before
 89  
      * packaging. By default everything is included. This option may be used
 90  
      * to implement the skinny WAR use case. Note that you can use the
 91  
      * Java Regular Expressions engine to include and exclude specific pattern
 92  
      * using the expression %regex[].
 93  
      *
 94  
      * @since 2.1-beta-1
 95  
      */
 96  
     @Parameter
 97  
     private String packagingIncludes;
 98  
 
 99  
     /**
 100  
      * The WAR archiver.
 101  
      */
 102  
     @Component( role = Archiver.class, hint = "war" )
 103  
     private WarArchiver warArchiver;
 104  
 
 105  
     /**
 106  
      */
 107  
     @Component
 108  
     private MavenProjectHelper projectHelper;
 109  
 
 110  
     /**
 111  
      * Whether this is the main artifact being built. Set to <code>false</code> if you don't want to install or
 112  
      * deploy it to the local repository instead of the default one in an execution.
 113  
      */
 114  
     @Parameter( property = "primaryArtifact", defaultValue = "true" )
 115  34
     private boolean primaryArtifact = true;
 116  
 
 117  
     /**
 118  
      * Whether or not to fail the build if the <code>web.xml</code> file is missing. Set to <code>false</code>
 119  
      * if you want you WAR built without a <code>web.xml</code> file.
 120  
      * This may be useful if you are building an overlay that has no web.xml file.
 121  
      *
 122  
      * @since 2.1-alpha-2
 123  
      */
 124  
     @Parameter( property = "failOnMissingWebXml", defaultValue = "true" )
 125  34
     private boolean failOnMissingWebXml = true;
 126  
 
 127  
     /**
 128  
      * Whether classes (that is the content of the WEB-INF/classes directory) should be attached to the
 129  
      * project as an additional artifact.
 130  
      * <p>By default the
 131  
      * classifier for the additional artifact is 'classes'.
 132  
      * You can change it with the
 133  
      * <code><![CDATA[<classesClassifier>someclassifier</classesClassifier>]]></code>
 134  
      * parameter.
 135  
      * </p><p>
 136  
      * If this parameter true, another project can depend on the classes
 137  
      * by writing something like:
 138  
      * <pre><![CDATA[<dependency>
 139  
      *   <groupId>myGroup</groupId>
 140  
      *   <artifactId>myArtifact</artifactId>
 141  
      *   <version>myVersion</myVersion>
 142  
      *   <classifier>classes</classifier>
 143  
      * </dependency>]]></pre></p>
 144  
      *
 145  
      * @since 2.1-alpha-2
 146  
      */
 147  
     @Parameter( defaultValue = "false" )
 148  34
     private boolean attachClasses = false;
 149  
 
 150  
     /**
 151  
      * The classifier to use for the attached classes artifact.
 152  
      *
 153  
      * @since 2.1-alpha-2
 154  
      */
 155  
     @Parameter( defaultValue = "classes" )
 156  34
     private String classesClassifier = "classes";
 157  
 
 158  
     // ----------------------------------------------------------------------
 159  
     // Implementation
 160  
     // ----------------------------------------------------------------------
 161  
 
 162  
 
 163  
     /**
 164  
      * Executes the WarMojo on the current project.
 165  
      *
 166  
      * @throws MojoExecutionException if an error occurred while building the webapp
 167  
      */
 168  
     public void execute()
 169  
         throws MojoExecutionException, MojoFailureException
 170  
     {
 171  30
         File warFile = getTargetWarFile();
 172  
 
 173  
         try
 174  
         {
 175  30
             performPackaging( warFile );
 176  
         }
 177  0
         catch ( DependencyResolutionRequiredException e )
 178  
         {
 179  0
             throw new MojoExecutionException( "Error assembling WAR: " + e.getMessage(), e );
 180  
         }
 181  0
         catch ( ManifestException e )
 182  
         {
 183  0
             throw new MojoExecutionException( "Error assembling WAR", e );
 184  
         }
 185  0
         catch ( IOException e )
 186  
         {
 187  0
             throw new MojoExecutionException( "Error assembling WAR", e );
 188  
         }
 189  2
         catch ( ArchiverException e )
 190  
         {
 191  2
             throw new MojoExecutionException( "Error assembling WAR: " + e.getMessage(), e );
 192  28
         }
 193  28
     }
 194  
 
 195  
     /**
 196  
      * Generates the webapp according to the <tt>mode</tt> attribute.
 197  
      *
 198  
      * @param warFile the target WAR file
 199  
      * @throws IOException            if an error occurred while copying files
 200  
      * @throws ArchiverException      if the archive could not be created
 201  
      * @throws ManifestException      if the manifest could not be created
 202  
      * @throws DependencyResolutionRequiredException
 203  
      *                                if an error occurred while resolving the dependencies
 204  
      * @throws MojoExecutionException if the execution failed
 205  
      * @throws MojoFailureException   if a fatal exception occurred
 206  
      */
 207  
     private void performPackaging( File warFile )
 208  
         throws IOException, ArchiverException, ManifestException, DependencyResolutionRequiredException,
 209  
         MojoExecutionException, MojoFailureException
 210  
     {
 211  30
         getLog().info( "Packaging webapp" );
 212  
 
 213  30
         buildExplodedWebapp( getWebappDirectory() );
 214  
 
 215  30
         MavenArchiver archiver = new MavenArchiver();
 216  
 
 217  30
         archiver.setArchiver( warArchiver );
 218  
 
 219  30
         archiver.setOutputFile( warFile );
 220  
 
 221  30
         getLog().debug(
 222  
             "Excluding " + Arrays.asList( getPackagingExcludes() ) + " from the generated webapp archive." );
 223  30
         getLog().debug(
 224  
             "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated webapp archive." );
 225  
 
 226  30
         warArchiver.addDirectory( getWebappDirectory(), getPackagingIncludes(), getPackagingExcludes() );
 227  
 
 228  30
         final File webXmlFile = new File( getWebappDirectory(), "WEB-INF/web.xml" );
 229  30
         if ( webXmlFile.exists() )
 230  
         {
 231  26
             warArchiver.setWebxml( webXmlFile );
 232  
         }
 233  
 
 234  30
         warArchiver.setRecompressAddedZips( isRecompressZippedFiles()  );
 235  
 
 236  30
         if ( !failOnMissingWebXml )
 237  
         {
 238  2
             getLog().debug( "Build won't fail if web.xml file is missing." );
 239  
             // The flag is wrong in plexus-archiver so it will need to be fixed at some point
 240  2
             warArchiver.setIgnoreWebxml( false );
 241  
         }
 242  
 
 243  
         // create archive
 244  30
         archiver.createArchive( getSession(), getProject(), getArchive() );
 245  
 
 246  
         // create the classes to be attached if necessary
 247  28
         if ( isAttachClasses() )
 248  
         {
 249  4
             if ( isArchiveClasses() && getJarArchiver().getDestFile() != null )
 250  
             {
 251  
                 // special handling in case of archived classes: MWAR-240
 252  0
                 File targetClassesFile = getTargetClassesFile();
 253  0
                 FileUtils.copyFile(getJarArchiver().getDestFile(), targetClassesFile);
 254  0
                 projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), targetClassesFile );
 255  0
             }
 256  
             else
 257  
             {
 258  4
                 ClassesPackager packager = new ClassesPackager();
 259  4
                 final File classesDirectory = packager.getClassesDirectory( getWebappDirectory() );
 260  4
                 if ( classesDirectory.exists() )
 261  
                 {
 262  4
                     getLog().info( "Packaging classes" );
 263  4
                     packager.packageClasses( classesDirectory, getTargetClassesFile(), getJarArchiver(), getSession(),
 264  
                                              getProject(), getArchive() );
 265  4
                     projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), getTargetClassesFile() );
 266  
                 }
 267  
             }
 268  
         }
 269  
 
 270  28
         String classifier = this.classifier;
 271  28
         if ( classifier != null )
 272  
         {
 273  2
             projectHelper.attachArtifact( getProject(), "war", classifier, warFile );
 274  
         }
 275  
         else
 276  
         {
 277  26
             Artifact artifact = getProject().getArtifact();
 278  26
             if ( primaryArtifact )
 279  
             {
 280  24
                 artifact.setFile( warFile );
 281  
             }
 282  2
             else if ( artifact.getFile() == null || artifact.getFile().isDirectory() )
 283  
             {
 284  0
                 artifact.setFile( warFile );
 285  
             }
 286  
         }
 287  28
     }
 288  
 
 289  
 
 290  
     protected static File getTargetFile( File basedir, String finalName, String classifier, String type )
 291  
     {
 292  38
         if ( classifier == null )
 293  
         {
 294  28
             classifier = "";
 295  
         }
 296  10
         else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
 297  
         {
 298  10
             classifier = "-" + classifier;
 299  
         }
 300  
 
 301  38
         return new File( basedir, finalName + classifier + "." + type );
 302  
     }
 303  
 
 304  
 
 305  
     protected File getTargetWarFile()
 306  
     {
 307  30
         return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassifier(), "war" );
 308  
 
 309  
     }
 310  
 
 311  
     protected File getTargetClassesFile()
 312  
     {
 313  8
         return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassesClassifier(), "jar" );
 314  
     }
 315  
 
 316  
     // Getters and Setters
 317  
 
 318  
     public String getClassifier()
 319  
     {
 320  30
         return classifier;
 321  
     }
 322  
 
 323  
     public void setClassifier( String classifier )
 324  
     {
 325  0
         this.classifier = classifier;
 326  0
     }
 327  
 
 328  
     public String[] getPackagingExcludes()
 329  
     {
 330  60
         if ( StringUtils.isEmpty( packagingExcludes ) )
 331  
         {
 332  60
             return new String[0];
 333  
         }
 334  
         else
 335  
         {
 336  0
             return StringUtils.split( packagingExcludes, "," );
 337  
         }
 338  
     }
 339  
 
 340  
     public void setPackagingExcludes( String packagingExcludes )
 341  
     {
 342  0
         this.packagingExcludes = packagingExcludes;
 343  0
     }
 344  
 
 345  
     public String[] getPackagingIncludes()
 346  
     {
 347  60
         if ( StringUtils.isEmpty( packagingIncludes ) )
 348  
         {
 349  56
             return new String[]{"**"};
 350  
         }
 351  
         else
 352  
         {
 353  4
             return StringUtils.split( packagingIncludes, "," );
 354  
         }
 355  
     }
 356  
 
 357  
     public void setPackagingIncludes( String packagingIncludes )
 358  
     {
 359  0
         this.packagingIncludes = packagingIncludes;
 360  0
     }
 361  
 
 362  
     public String getOutputDirectory()
 363  
     {
 364  38
         return outputDirectory;
 365  
     }
 366  
 
 367  
     public void setOutputDirectory( String outputDirectory )
 368  
     {
 369  0
         this.outputDirectory = outputDirectory;
 370  0
     }
 371  
 
 372  
     public String getWarName()
 373  
     {
 374  38
         return warName;
 375  
     }
 376  
 
 377  
     public void setWarName( String warName )
 378  
     {
 379  0
         this.warName = warName;
 380  0
     }
 381  
 
 382  
     public WarArchiver getWarArchiver()
 383  
     {
 384  0
         return warArchiver;
 385  
     }
 386  
 
 387  
     public void setWarArchiver( WarArchiver warArchiver )
 388  
     {
 389  0
         this.warArchiver = warArchiver;
 390  0
     }
 391  
 
 392  
     public MavenProjectHelper getProjectHelper()
 393  
     {
 394  0
         return projectHelper;
 395  
     }
 396  
 
 397  
     public void setProjectHelper( MavenProjectHelper projectHelper )
 398  
     {
 399  0
         this.projectHelper = projectHelper;
 400  0
     }
 401  
 
 402  
     public boolean isPrimaryArtifact()
 403  
     {
 404  0
         return primaryArtifact;
 405  
     }
 406  
 
 407  
     public void setPrimaryArtifact( boolean primaryArtifact )
 408  
     {
 409  26
         this.primaryArtifact = primaryArtifact;
 410  26
     }
 411  
 
 412  
     public boolean isAttachClasses()
 413  
     {
 414  28
         return attachClasses;
 415  
     }
 416  
 
 417  
     public void setAttachClasses( boolean attachClasses )
 418  
     {
 419  4
         this.attachClasses = attachClasses;
 420  4
     }
 421  
 
 422  
     public String getClassesClassifier()
 423  
     {
 424  12
         return classesClassifier;
 425  
     }
 426  
 
 427  
     public void setClassesClassifier( String classesClassifier )
 428  
     {
 429  2
         this.classesClassifier = classesClassifier;
 430  2
     }
 431  
 
 432  
     public boolean isFailOnMissingWebXml()
 433  
     {
 434  0
         return failOnMissingWebXml;
 435  
     }
 436  
 
 437  
     public void setFailOnMissingWebXml( boolean failOnMissingWebXml )
 438  
     {
 439  4
         this.failOnMissingWebXml = failOnMissingWebXml;
 440  4
     }
 441  
 }