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