Coverage Report - org.apache.maven.plugin.source.AbstractSourceJarMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractSourceJarMojo
68%
75/111
58%
35/60
3.667
 
 1  
 package org.apache.maven.plugin.source;
 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.artifact.DependencyResolutionRequiredException;
 25  
 import org.apache.maven.model.Resource;
 26  
 import org.apache.maven.plugin.AbstractMojo;
 27  
 import org.apache.maven.plugin.MojoExecutionException;
 28  
 import org.apache.maven.project.MavenProject;
 29  
 import org.apache.maven.project.MavenProjectHelper;
 30  
 import org.codehaus.plexus.archiver.Archiver;
 31  
 import org.codehaus.plexus.archiver.ArchiverException;
 32  
 import org.codehaus.plexus.archiver.jar.JarArchiver;
 33  
 import org.codehaus.plexus.archiver.jar.ManifestException;
 34  
 import org.codehaus.plexus.util.FileUtils;
 35  
 
 36  
 import java.io.File;
 37  
 import java.io.IOException;
 38  
 import java.util.ArrayList;
 39  
 import java.util.Arrays;
 40  
 import java.util.Iterator;
 41  
 import java.util.List;
 42  
 
 43  
 /**
 44  
  * Base class for bundling sources into a jar archive.
 45  
  * 
 46  
  * @version $Id: AbstractSourceJarMojo.java 763422 2009-04-08 21:59:54Z pgier $
 47  
  * @since 2.0.3
 48  
  */
 49  16
 public abstract class AbstractSourceJarMojo
 50  
     extends AbstractMojo
 51  
 {
 52  2
     private static final String[] DEFAULT_INCLUDES = new String[] { "**/*" };
 53  
 
 54  2
     private static final String[] DEFAULT_EXCLUDES = new String[] {};
 55  
 
 56  
     /**
 57  
      * List of files to include. Specified as fileset patterns which are relative to the input directory whose contents
 58  
      * is being packaged into the JAR.
 59  
      * 
 60  
      * @parameter
 61  
      * @since 2.1
 62  
      */
 63  
     private String[] includes;
 64  
 
 65  
     /**
 66  
      * List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents
 67  
      * is being packaged into the JAR.
 68  
      * 
 69  
      * @parameter
 70  
      * @since 2.1
 71  
      */
 72  
     private String[] excludes;
 73  
 
 74  
     /**
 75  
      * Exclude commonly excluded files such as SCM configuration. These are defined in the plexus
 76  
      * FileUtils.getDefaultExcludes()
 77  
      * 
 78  
      * @parameter default-value="true"
 79  
      * @since 2.1
 80  
      */
 81  
     private boolean useDefaultExcludes;
 82  
 
 83  
     /**
 84  
      * The Maven Project Object
 85  
      * 
 86  
      * @parameter expression="${project}"
 87  
      * @readonly
 88  
      * @required
 89  
      */
 90  
     protected MavenProject project;
 91  
 
 92  
     /**
 93  
      * The Jar archiver.
 94  
      *
 95  
      * @component role="org.codehaus.plexus.archiver.Archiver" roleHint="jar"
 96  
      */
 97  
     private JarArchiver jarArchiver;
 98  
 
 99  
     /**
 100  
      * The archive configuration to use. See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven
 101  
      * Archiver Reference</a>.
 102  
      * 
 103  
      * @parameter
 104  
      * @since 2.1
 105  
      */
 106  16
     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
 107  
 
 108  
     /**
 109  
      * Path to the default MANIFEST file to use. It will be used if <code>useDefaultManifestFile</code> is set to
 110  
      * <code>true</code>.
 111  
      *
 112  
      * @parameter default-value="${project.build.outputDirectory}/META-INF/MANIFEST.MF"
 113  
      * @required
 114  
      * @readonly
 115  
      * @since 2.1
 116  
      */
 117  
     private File defaultManifestFile;
 118  
 
 119  
     /**
 120  
      * Set this to <code>true</code> to enable the use of the <code>defaultManifestFile</code>. <br/>
 121  
      *
 122  
      * @parameter default-value="false"
 123  
      * @since 2.1
 124  
      */
 125  
     private boolean useDefaultManifestFile;
 126  
 
 127  
     /**
 128  
      * Specifies whether or not to attach the artifact to the project
 129  
      *
 130  
      * @parameter expression="${attach}" default-value="true"
 131  
      */
 132  
     private boolean attach;
 133  
 
 134  
     /**
 135  
      * Specifies whether or not to exclude resources from the sources-jar. This
 136  
      * can be convenient if your project includes large resources, such as
 137  
      * images, and you don't want to include them in the sources-jar.
 138  
      *
 139  
      * @parameter expression="${source.excludeResources}" default-value="false"
 140  
      * @since 2.0.4
 141  
      */
 142  
     protected boolean excludeResources;
 143  
 
 144  
     /**
 145  
      * Specifies whether or not to include the POM file in the sources-jar.
 146  
      *
 147  
      * @parameter expression="${source.includePom}" default-value="false"
 148  
      * @since 2.1
 149  
      */
 150  
     protected boolean includePom;
 151  
 
 152  
     /**
 153  
      * Used for attaching the source jar to the project.
 154  
      *
 155  
      * @component
 156  
      */
 157  
     private MavenProjectHelper projectHelper;
 158  
 
 159  
     /**
 160  
      * The directory where the generated archive file will be put.
 161  
      *
 162  
      * @parameter default-value="${project.build.directory}"
 163  
      */
 164  
     protected File outputDirectory;
 165  
 
 166  
     /**
 167  
      * The filename to be used for the generated archive file.
 168  
      * For the source:jar goal, "-sources" is appended to this filename.
 169  
      * For the source:test-jar goal, "-test-sources" is appended.
 170  
      *
 171  
      * @parameter default-value="${project.build.finalName}"
 172  
      */
 173  
     protected String finalName;
 174  
 
 175  
     /**
 176  
      * Contains the full list of projects in the reactor.
 177  
      *
 178  
      * @parameter expression="${reactorProjects}"
 179  
      * @readonly
 180  
      */
 181  
     protected List reactorProjects;
 182  
 
 183  
     /**
 184  
      * Whether creating the archive should be forced.  If set to true, the jar will
 185  
      * always be created.  If set to false, the jar will only be created when the
 186  
      * sources are newer than the jar.
 187  
      *
 188  
      * @parameter expression="${source.forceCreation}" default-value="false"
 189  
      * @since 2.1
 190  
      */
 191  
     private boolean forceCreation;
 192  
 
 193  
     // ----------------------------------------------------------------------
 194  
     // Public methods
 195  
     // ----------------------------------------------------------------------
 196  
 
 197  
     /** {@inheritDoc} */
 198  
     public void execute()
 199  
         throws MojoExecutionException
 200  
     {
 201  16
         packageSources( project );
 202  16
     }
 203  
 
 204  
     // ----------------------------------------------------------------------
 205  
     // Protected methods
 206  
     // ----------------------------------------------------------------------
 207  
 
 208  
     /**
 209  
      * @return the wanted classifier, ie <code>sources</code> or <code>test-sources</code>
 210  
      */
 211  
     protected abstract String getClassifier();
 212  
 
 213  
     /**
 214  
      * @param p not null
 215  
      * @return the compile or test sources
 216  
      */
 217  
     protected abstract List getSources( MavenProject p )
 218  
         throws MojoExecutionException;
 219  
 
 220  
     /**
 221  
      * @param p not null
 222  
      * @return the compile or test resources
 223  
      */
 224  
     protected abstract List getResources( MavenProject p )
 225  
         throws MojoExecutionException;
 226  
 
 227  
     protected void packageSources( MavenProject p )
 228  
         throws MojoExecutionException
 229  
     {
 230  16
         if ( !"pom".equals( p.getPackaging() ) )
 231  
         {
 232  12
             packageSources( Arrays.asList( new Object[] { p } ) );
 233  
         }
 234  16
     }
 235  
 
 236  
     protected void packageSources( List projects )
 237  
         throws MojoExecutionException
 238  
     {
 239  12
         if ( project.getArtifact().getClassifier() != null )
 240  
         {
 241  0
             getLog().warn( "NOT adding sources to artifacts with classifier as Maven only supports one classifier "
 242  
                 + "per artifact. Current artifact [" + project.getArtifact().getId() + "] has a ["
 243  
                 + project.getArtifact().getClassifier() + "] classifier." );
 244  
 
 245  0
             return;
 246  
         }
 247  
 
 248  12
         MavenArchiver archiver = createArchiver();
 249  
 
 250  12
         for ( Iterator i = projects.iterator(); i.hasNext(); )
 251  
         {
 252  12
             MavenProject subProject = getProject( (MavenProject) i.next() );
 253  
 
 254  12
             if ( "pom".equals( subProject.getPackaging() ) )
 255  
             {
 256  0
                 continue;
 257  
             }
 258  
 
 259  12
             archiveProjectContent( subProject, archiver.getArchiver() );
 260  12
         }
 261  
 
 262  12
         if ( useDefaultManifestFile && defaultManifestFile.exists() && archive.getManifestFile() == null )
 263  
         {
 264  0
             getLog().info( "Adding existing MANIFEST to archive. Found under: " + defaultManifestFile.getPath() );
 265  0
             archive.setManifestFile( defaultManifestFile );
 266  
         }
 267  
 
 268  12
         File outputFile = new File( outputDirectory, finalName + "-" + getClassifier() + getExtension() );
 269  
         
 270  
         try
 271  
         {
 272  12
             archiver.setOutputFile( outputFile );
 273  
 
 274  12
             archive.setAddMavenDescriptor( false );
 275  12
             archive.setForced( forceCreation );
 276  
 
 277  12
             archiver.createArchive( project, archive );
 278  
         }
 279  0
         catch ( IOException e )
 280  
         {
 281  0
             throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 282  
         }
 283  0
         catch ( ArchiverException e )
 284  
         {
 285  0
             throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 286  
         }
 287  0
         catch ( DependencyResolutionRequiredException e )
 288  
         {
 289  0
             throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 290  
         }
 291  0
         catch ( ManifestException e )
 292  
         {
 293  0
             throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 294  12
         }
 295  
 
 296  12
         if ( attach )
 297  
         {
 298  0
             projectHelper.attachArtifact( project, getType(), getClassifier(), outputFile );
 299  
         }
 300  
         else
 301  
         {
 302  12
             getLog().info( "NOT adding java-sources to attached artifacts list." );
 303  
         }
 304  12
     }
 305  
 
 306  
     protected void archiveProjectContent( MavenProject p, Archiver archiver )
 307  
         throws MojoExecutionException
 308  
     {
 309  12
         if ( includePom )
 310  
         {
 311  
             try
 312  
             {
 313  2
                 archiver.addFile( p.getFile(), p.getFile().getName() );
 314  
             }
 315  0
             catch ( ArchiverException e )
 316  
             {
 317  0
                 throw new MojoExecutionException( "Error adding POM file to target jar file.", e );
 318  2
             }
 319  
         }
 320  
 
 321  12
         for ( Iterator i = getSources( p ).iterator(); i.hasNext(); )
 322  
         {
 323  12
             String s = (String) i.next();
 324  
 
 325  12
             File sourceDirectory = new File( s );
 326  
 
 327  12
             if ( sourceDirectory.exists() )
 328  
             {
 329  12
                 addDirectory( archiver, sourceDirectory, getCombinedIncludes( null ), getCombinedExcludes( null ) );
 330  
             }
 331  12
         }
 332  
 
 333  
         //MAPI: this should be taken from the resources plugin
 334  12
         for ( Iterator i = getResources( p ).iterator(); i.hasNext(); )
 335  
         {
 336  12
             Resource resource = (Resource) i.next();
 337  
 
 338  12
             File sourceDirectory = new File( resource.getDirectory() );
 339  
 
 340  12
             if ( !sourceDirectory.exists() )
 341  
             {
 342  0
                 continue;
 343  
             }
 344  
 
 345  12
             List resourceIncludes = resource.getIncludes();
 346  
 
 347  12
             String[] combinedIncludes = getCombinedIncludes( resourceIncludes );
 348  
 
 349  12
             List resourceExcludes = resource.getExcludes();
 350  
 
 351  12
             String[] combinedExcludes = getCombinedExcludes( resourceExcludes );
 352  
 
 353  12
             String targetPath = resource.getTargetPath();
 354  12
             if ( targetPath != null )
 355  
             {
 356  0
                 if ( !targetPath.trim().endsWith( "/" ) )
 357  
                 {
 358  0
                     targetPath += "/";
 359  
                 }
 360  0
                 addDirectory( archiver, sourceDirectory, targetPath, combinedIncludes, combinedExcludes );
 361  
             }
 362  
             else
 363  
             {
 364  12
                 addDirectory( archiver, sourceDirectory, combinedIncludes, combinedExcludes );
 365  
             }
 366  12
         }
 367  12
     }
 368  
 
 369  
     protected MavenArchiver createArchiver()
 370  
         throws MojoExecutionException
 371  
     {
 372  12
         MavenArchiver archiver = new MavenArchiver();
 373  12
         archiver.setArchiver( jarArchiver );
 374  
 
 375  12
         if ( project.getBuild() != null )
 376  
         {
 377  12
             List resources = project.getBuild().getResources();
 378  
 
 379  12
             for ( Iterator i = resources.iterator(); i.hasNext(); )
 380  
             {
 381  0
                 Resource r = (Resource) i.next();
 382  
 
 383  0
                 if ( r.getDirectory().endsWith( "maven-shared-archive-resources" ) )
 384  
                 {
 385  0
                     addDirectory( archiver.getArchiver(), new File( r.getDirectory() ), getCombinedIncludes( null ),
 386  
                                   getCombinedExcludes( null ) );
 387  
                 }
 388  0
             }
 389  
         }
 390  
 
 391  12
         return archiver;
 392  
     }
 393  
 
 394  
     protected void addDirectory( Archiver archiver, File sourceDirectory, String[] includes, String[] excludes )
 395  
         throws MojoExecutionException
 396  
     {
 397  
         try
 398  
         {
 399  24
             archiver.addDirectory( sourceDirectory, includes, excludes );
 400  
         }
 401  0
         catch ( ArchiverException e )
 402  
         {
 403  0
             throw new MojoExecutionException( "Error adding directory to source archive.", e );
 404  24
         }
 405  24
     }
 406  
 
 407  
     protected void addDirectory( Archiver archiver, File sourceDirectory, String prefix, String[] includes,
 408  
                                  String[] excludes )
 409  
         throws MojoExecutionException
 410  
     {
 411  
         try
 412  
         {
 413  0
             archiver.addDirectory( sourceDirectory, prefix, includes, excludes );
 414  
         }
 415  0
         catch ( ArchiverException e )
 416  
         {
 417  0
             throw new MojoExecutionException( "Error adding directory to source archive.", e );
 418  0
         }
 419  0
     }
 420  
 
 421  
     protected String getExtension()
 422  
     {
 423  12
         return ".jar";
 424  
     }
 425  
 
 426  
     protected MavenProject getProject( MavenProject p )
 427  
     {
 428  12
         if ( p.getExecutionProject() != null )
 429  
         {
 430  0
             return p.getExecutionProject();
 431  
         }
 432  
 
 433  12
         return p;
 434  
     }
 435  
 
 436  
     protected String getType()
 437  
     {
 438  0
         return "java-source";
 439  
     }
 440  
 
 441  
     /**
 442  
      * Combines the includes parameter and additional includes. Defaults to {@link #DEFAULT_INCLUDES} If the
 443  
      * additionalIncludes parameter is null, it is not added to the combined includes.
 444  
      * 
 445  
      * @param additionalIncludes The includes specified in the pom resources section
 446  
      * @return The combined array of includes.
 447  
      */
 448  
     private String[] getCombinedIncludes( List additionalIncludes )
 449  
     {
 450  24
         ArrayList combinedIncludes = new ArrayList();
 451  
 
 452  24
         if ( includes != null && includes.length > 0 )
 453  
         {
 454  0
             combinedIncludes.addAll( Arrays.asList( includes ) );
 455  
         }
 456  
 
 457  24
         if ( additionalIncludes != null && additionalIncludes.size() > 0 )
 458  
         {
 459  2
             combinedIncludes.addAll( additionalIncludes );
 460  
         }
 461  
 
 462  
         // If there are no other includes, use the default.
 463  24
         if ( combinedIncludes.size() == 0 )
 464  
         {
 465  22
             combinedIncludes.addAll( Arrays.asList( DEFAULT_INCLUDES ) );
 466  
         }
 467  
 
 468  24
         return (String[]) combinedIncludes.toArray( new String[combinedIncludes.size()] );
 469  
     }
 470  
 
 471  
     /**
 472  
      * Combines the user parameter {@link #excludes}, the default excludes from plexus FileUtils,
 473  
      * and the contents of the parameter addionalExcludes.
 474  
      * 
 475  
      * @param additionalExcludes Additional excludes to add to the array
 476  
      * @return The combined list of excludes.
 477  
      */
 478  
 
 479  
     private String[] getCombinedExcludes( List additionalExcludes )
 480  
     {
 481  24
         ArrayList combinedExcludes = new ArrayList();
 482  
 
 483  24
         if ( useDefaultExcludes )
 484  
         {
 485  0
             combinedExcludes.addAll( FileUtils.getDefaultExcludesAsList() );
 486  
         }
 487  
 
 488  24
         if ( excludes != null && excludes.length > 0 )
 489  
         {
 490  0
             combinedExcludes.addAll( Arrays.asList( excludes ) );
 491  
         }
 492  
 
 493  24
         if ( additionalExcludes != null && additionalExcludes.size() > 0 )
 494  
         {
 495  4
             combinedExcludes.addAll( additionalExcludes );
 496  
         }
 497  
 
 498  24
         if ( combinedExcludes.size() == 0 )
 499  
         {
 500  20
             combinedExcludes.addAll( Arrays.asList( DEFAULT_EXCLUDES ) );
 501  
         }
 502  
 
 503  24
         return (String[]) combinedExcludes.toArray( new String[combinedExcludes.size()] );
 504  
     }
 505  
 }