Coverage Report - org.apache.maven.plugin.source.AbstractSourceJarMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractSourceJarMojo
68%
77/114
58%
36/62
3,733
 
 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 824199 2009-10-11 23:30:47Z aheritier $
 47  
  * @since 2.0.3
 48  
  */
 49  8
 public abstract class AbstractSourceJarMojo
 50  
     extends AbstractMojo
 51  
 {
 52  1
     private static final String[] DEFAULT_INCLUDES = new String[] { "**/*" };
 53  
 
 54  1
     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  8
     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  8
         packageSources( project );
 202  8
     }
 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  8
         if ( !"pom".equals( p.getPackaging() ) )
 231  
         {
 232  6
             packageSources( Arrays.asList( new Object[] { p } ) );
 233  
         }
 234  8
     }
 235  
 
 236  
     protected void packageSources( List projects )
 237  
         throws MojoExecutionException
 238  
     {
 239  6
         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  6
         MavenArchiver archiver = createArchiver();
 249  
 
 250  6
         for ( Iterator i = projects.iterator(); i.hasNext(); )
 251  
         {
 252  6
             MavenProject subProject = getProject( (MavenProject) i.next() );
 253  
 
 254  6
             if ( "pom".equals( subProject.getPackaging() ) )
 255  
             {
 256  0
                 continue;
 257  
             }
 258  
 
 259  6
             archiveProjectContent( subProject, archiver.getArchiver() );
 260  6
         }
 261  
 
 262  6
         if(!archiver.getArchiver().getFiles().isEmpty()){
 263  
         
 264  6
             if ( useDefaultManifestFile && defaultManifestFile.exists() && archive.getManifestFile() == null )
 265  
             {
 266  0
                 getLog().info( "Adding existing MANIFEST to archive. Found under: " + defaultManifestFile.getPath() );
 267  0
                 archive.setManifestFile( defaultManifestFile );
 268  
             }
 269  
     
 270  6
             File outputFile = new File( outputDirectory, finalName + "-" + getClassifier() + getExtension() );
 271  
             
 272  
             try
 273  
             {
 274  6
                 archiver.setOutputFile( outputFile );
 275  
     
 276  6
                 archive.setAddMavenDescriptor( false );
 277  6
                 archive.setForced( forceCreation );
 278  
     
 279  6
                 archiver.createArchive( project, archive );
 280  
             }
 281  0
             catch ( IOException e )
 282  
             {
 283  0
                 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 284  
             }
 285  0
             catch ( ArchiverException e )
 286  
             {
 287  0
                 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 288  
             }
 289  0
             catch ( DependencyResolutionRequiredException e )
 290  
             {
 291  0
                 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 292  
             }
 293  0
             catch ( ManifestException e )
 294  
             {
 295  0
                 throw new MojoExecutionException( "Error creating source archive: " + e.getMessage(), e );
 296  6
             }
 297  
     
 298  6
             if ( attach )
 299  
             {
 300  0
                 projectHelper.attachArtifact( project, getType(), getClassifier(), outputFile );
 301  
             }
 302  
             else
 303  
             {
 304  6
                 getLog().info( "NOT adding java-sources to attached artifacts list." );
 305  
             }
 306  6
         }
 307  
         else
 308  
         {
 309  0
             getLog().info( "No sources in project. Archive not created." );
 310  
         }
 311  6
     }
 312  
 
 313  
     protected void archiveProjectContent( MavenProject p, Archiver archiver )
 314  
         throws MojoExecutionException
 315  
     {
 316  6
         if ( includePom )
 317  
         {
 318  
             try
 319  
             {
 320  1
                 archiver.addFile( p.getFile(), p.getFile().getName() );
 321  
             }
 322  0
             catch ( ArchiverException e )
 323  
             {
 324  0
                 throw new MojoExecutionException( "Error adding POM file to target jar file.", e );
 325  1
             }
 326  
         }
 327  
 
 328  6
         for ( Iterator i = getSources( p ).iterator(); i.hasNext(); )
 329  
         {
 330  6
             String s = (String) i.next();
 331  
 
 332  6
             File sourceDirectory = new File( s );
 333  
 
 334  6
             if ( sourceDirectory.exists() )
 335  
             {
 336  6
                 addDirectory( archiver, sourceDirectory, getCombinedIncludes( null ), getCombinedExcludes( null ) );
 337  
             }
 338  6
         }
 339  
 
 340  
         //MAPI: this should be taken from the resources plugin
 341  6
         for ( Iterator i = getResources( p ).iterator(); i.hasNext(); )
 342  
         {
 343  6
             Resource resource = (Resource) i.next();
 344  
 
 345  6
             File sourceDirectory = new File( resource.getDirectory() );
 346  
 
 347  6
             if ( !sourceDirectory.exists() )
 348  
             {
 349  0
                 continue;
 350  
             }
 351  
 
 352  6
             List resourceIncludes = resource.getIncludes();
 353  
 
 354  6
             String[] combinedIncludes = getCombinedIncludes( resourceIncludes );
 355  
 
 356  6
             List resourceExcludes = resource.getExcludes();
 357  
 
 358  6
             String[] combinedExcludes = getCombinedExcludes( resourceExcludes );
 359  
 
 360  6
             String targetPath = resource.getTargetPath();
 361  6
             if ( targetPath != null )
 362  
             {
 363  0
                 if ( !targetPath.trim().endsWith( "/" ) )
 364  
                 {
 365  0
                     targetPath += "/";
 366  
                 }
 367  0
                 addDirectory( archiver, sourceDirectory, targetPath, combinedIncludes, combinedExcludes );
 368  
             }
 369  
             else
 370  
             {
 371  6
                 addDirectory( archiver, sourceDirectory, combinedIncludes, combinedExcludes );
 372  
             }
 373  6
         }
 374  6
     }
 375  
 
 376  
     protected MavenArchiver createArchiver()
 377  
         throws MojoExecutionException
 378  
     {
 379  6
         MavenArchiver archiver = new MavenArchiver();
 380  6
         archiver.setArchiver( jarArchiver );
 381  
 
 382  6
         if ( project.getBuild() != null )
 383  
         {
 384  6
             List resources = project.getBuild().getResources();
 385  
 
 386  6
             for ( Iterator i = resources.iterator(); i.hasNext(); )
 387  
             {
 388  0
                 Resource r = (Resource) i.next();
 389  
 
 390  0
                 if ( r.getDirectory().endsWith( "maven-shared-archive-resources" ) )
 391  
                 {
 392  0
                     addDirectory( archiver.getArchiver(), new File( r.getDirectory() ), getCombinedIncludes( null ),
 393  
                                   getCombinedExcludes( null ) );
 394  
                 }
 395  0
             }
 396  
         }
 397  
 
 398  6
         return archiver;
 399  
     }
 400  
 
 401  
     protected void addDirectory( Archiver archiver, File sourceDirectory, String[] includes, String[] excludes )
 402  
         throws MojoExecutionException
 403  
     {
 404  
         try
 405  
         {
 406  12
             archiver.addDirectory( sourceDirectory, includes, excludes );
 407  
         }
 408  0
         catch ( ArchiverException e )
 409  
         {
 410  0
             throw new MojoExecutionException( "Error adding directory to source archive.", e );
 411  12
         }
 412  12
     }
 413  
 
 414  
     protected void addDirectory( Archiver archiver, File sourceDirectory, String prefix, String[] includes,
 415  
                                  String[] excludes )
 416  
         throws MojoExecutionException
 417  
     {
 418  
         try
 419  
         {
 420  0
             archiver.addDirectory( sourceDirectory, prefix, includes, excludes );
 421  
         }
 422  0
         catch ( ArchiverException e )
 423  
         {
 424  0
             throw new MojoExecutionException( "Error adding directory to source archive.", e );
 425  0
         }
 426  0
     }
 427  
 
 428  
     protected String getExtension()
 429  
     {
 430  6
         return ".jar";
 431  
     }
 432  
 
 433  
     protected MavenProject getProject( MavenProject p )
 434  
     {
 435  6
         if ( p.getExecutionProject() != null )
 436  
         {
 437  0
             return p.getExecutionProject();
 438  
         }
 439  
 
 440  6
         return p;
 441  
     }
 442  
 
 443  
     protected String getType()
 444  
     {
 445  0
         return "java-source";
 446  
     }
 447  
 
 448  
     /**
 449  
      * Combines the includes parameter and additional includes. Defaults to {@link #DEFAULT_INCLUDES} If the
 450  
      * additionalIncludes parameter is null, it is not added to the combined includes.
 451  
      * 
 452  
      * @param additionalIncludes The includes specified in the pom resources section
 453  
      * @return The combined array of includes.
 454  
      */
 455  
     private String[] getCombinedIncludes( List additionalIncludes )
 456  
     {
 457  12
         ArrayList combinedIncludes = new ArrayList();
 458  
 
 459  12
         if ( includes != null && includes.length > 0 )
 460  
         {
 461  0
             combinedIncludes.addAll( Arrays.asList( includes ) );
 462  
         }
 463  
 
 464  12
         if ( additionalIncludes != null && additionalIncludes.size() > 0 )
 465  
         {
 466  1
             combinedIncludes.addAll( additionalIncludes );
 467  
         }
 468  
 
 469  
         // If there are no other includes, use the default.
 470  12
         if ( combinedIncludes.size() == 0 )
 471  
         {
 472  11
             combinedIncludes.addAll( Arrays.asList( DEFAULT_INCLUDES ) );
 473  
         }
 474  
 
 475  12
         return (String[]) combinedIncludes.toArray( new String[combinedIncludes.size()] );
 476  
     }
 477  
 
 478  
     /**
 479  
      * Combines the user parameter {@link #excludes}, the default excludes from plexus FileUtils,
 480  
      * and the contents of the parameter addionalExcludes.
 481  
      * 
 482  
      * @param additionalExcludes Additional excludes to add to the array
 483  
      * @return The combined list of excludes.
 484  
      */
 485  
 
 486  
     private String[] getCombinedExcludes( List additionalExcludes )
 487  
     {
 488  12
         ArrayList combinedExcludes = new ArrayList();
 489  
 
 490  12
         if ( useDefaultExcludes )
 491  
         {
 492  0
             combinedExcludes.addAll( FileUtils.getDefaultExcludesAsList() );
 493  
         }
 494  
 
 495  12
         if ( excludes != null && excludes.length > 0 )
 496  
         {
 497  0
             combinedExcludes.addAll( Arrays.asList( excludes ) );
 498  
         }
 499  
 
 500  12
         if ( additionalExcludes != null && additionalExcludes.size() > 0 )
 501  
         {
 502  2
             combinedExcludes.addAll( additionalExcludes );
 503  
         }
 504  
 
 505  12
         if ( combinedExcludes.size() == 0 )
 506  
         {
 507  10
             combinedExcludes.addAll( Arrays.asList( DEFAULT_EXCLUDES ) );
 508  
         }
 509  
 
 510  12
         return (String[]) combinedExcludes.toArray( new String[combinedExcludes.size()] );
 511  
     }
 512  
 }