Coverage Report - org.apache.maven.plugin.dependency.PurgeLocalRepositoryMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
PurgeLocalRepositoryMojo
0%
0/146
0%
0/64
5.333
PurgeLocalRepositoryMojo$1
N/A
N/A
5.333
PurgeLocalRepositoryMojo$DirectDependencyFilter
0%
0/19
0%
0/12
5.333
PurgeLocalRepositoryMojo$SnapshotsFilter
0%
0/2
N/A
5.333
PurgeLocalRepositoryMojo$SystemScopeExcludeFilter
0%
0/2
0%
0/2
5.333
 
 1  
 package org.apache.maven.plugin.dependency;
 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.artifact.Artifact;
 23  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 24  
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
 25  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 26  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 27  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 28  
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 29  
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 30  
 import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
 31  
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 32  
 import org.apache.maven.plugin.AbstractMojo;
 33  
 import org.apache.maven.plugin.MojoExecutionException;
 34  
 import org.apache.maven.plugin.MojoFailureException;
 35  
 import org.apache.maven.plugins.annotations.Component;
 36  
 import org.apache.maven.plugins.annotations.Mojo;
 37  
 import org.apache.maven.plugins.annotations.Parameter;
 38  
 import org.apache.maven.project.MavenProject;
 39  
 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
 40  
 import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
 41  
 import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
 42  
 import org.codehaus.plexus.util.FileUtils;
 43  
 import org.codehaus.plexus.util.StringUtils;
 44  
 
 45  
 import java.io.File;
 46  
 import java.io.IOException;
 47  
 import java.util.ArrayList;
 48  
 import java.util.Arrays;
 49  
 import java.util.LinkedHashSet;
 50  
 import java.util.List;
 51  
 import java.util.Set;
 52  
 
 53  
 /**
 54  
  * Remove the project dependencies from the local repository, and optionally re-resolve them.
 55  
  * 
 56  
  * @author jdcasey
 57  
  * @version $Id: PurgeLocalRepositoryMojo.java 1401976 2012-10-25 05:04:29Z pgier $
 58  
  * @since 2.0
 59  
  */
 60  
 @Mojo( name = "purge-local-repository", threadSafe = true )
 61  0
 public class PurgeLocalRepositoryMojo
 62  
     extends AbstractMojo
 63  
 {
 64  
 
 65  
     public static final String FILE_FUZZINESS = "file";
 66  
 
 67  
     public static final String VERSION_FUZZINESS = "version";
 68  
 
 69  
     public static final String ARTIFACT_ID_FUZZINESS = "artifactId";
 70  
 
 71  
     public static final String GROUP_ID_FUZZINESS = "groupId";
 72  
 
 73  
     /**
 74  
      * The current Maven project.
 75  
      */
 76  
     @Component
 77  
     private MavenProject project;
 78  
 
 79  
     /**
 80  
      * The list of dependencies in the form of groupId:artifactId which should BE deleted/purged from the local
 81  
      * repository. Note that using this parameter will deactivate the normal process for purging the current project
 82  
      * dependency tree. If this parameter is used, only the included artifacts will be purged. The manualIncludes
 83  
      * parameter should not be used in combination with the includes/excludes parameters.
 84  
      * 
 85  
      * @since 2.6
 86  
      */
 87  
     @Parameter
 88  
     private List<String> manualIncludes;
 89  
 
 90  
     /**
 91  
      * Comma-separated list of groupId:artifactId entries, which should be used to manually include artifacts for
 92  
      * deletion. This is a command-line alternative to the <code>manualIncludes</code> parameter, since List parameters
 93  
      * are not currently compatible with CLI specification.
 94  
      * 
 95  
      * @since 2.6
 96  
      */
 97  
     @Parameter( property = "manualInclude" )
 98  
     private String manualInclude;
 99  
 
 100  
     /**
 101  
      * The list of dependencies in the form of groupId:artifactId which should BE deleted/refreshed.
 102  
      * 
 103  
      * @since 2.6
 104  
      */
 105  
     @Parameter
 106  
     private List<String> includes;
 107  
 
 108  
     /**
 109  
      * Comma-separated list of groupId:artifactId entries, which should be used to include artifacts for
 110  
      * deletion/refresh. This is a command-line alternative to the <code>includes</code> parameter, since List
 111  
      * parameters are not currently compatible with CLI specification.
 112  
      * 
 113  
      * @since 2.6
 114  
      */
 115  
     @Parameter( property = "include" )
 116  
     private String include;
 117  
 
 118  
     /**
 119  
      * The list of dependencies in the form of groupId:artifactId which should NOT be deleted/refreshed.
 120  
      */
 121  
     @Parameter
 122  
     private List<String> excludes;
 123  
 
 124  
     /**
 125  
      * Comma-separated list of groupId:artifactId entries, which should be used to exclude artifacts from
 126  
      * deletion/refresh. This is a command-line alternative to the <code>excludes</code> parameter, since List
 127  
      * parameters are not currently compatible with CLI specification.
 128  
      */
 129  
     @Parameter( property = "exclude" )
 130  
     private String exclude;
 131  
 
 132  
     /**
 133  
      * Whether to re-resolve the artifacts once they have been deleted from the local repository. If you are running
 134  
      * this mojo from the command-line, you may want to disable this. By default, artifacts will be re-resolved.
 135  
      */
 136  
     @Parameter( property = "reResolve", defaultValue = "true" )
 137  
     private boolean reResolve;
 138  
 
 139  
     /**
 140  
      * The local repository, from which to delete artifacts.
 141  
      */
 142  
     @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
 143  
     private ArtifactRepository localRepository;
 144  
 
 145  
     /**
 146  
      * List of Remote Repositories used by the resolver
 147  
      */
 148  
     @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
 149  
     protected List<ArtifactRepository> remoteRepositories;
 150  
 
 151  
     /**
 152  
      * The artifact resolver used to re-resolve dependencies, if that option is enabled.
 153  
      */
 154  
     @Component
 155  
     private ArtifactResolver resolver;
 156  
 
 157  
     /**
 158  
      * The artifact metadata source used to resolve dependencies
 159  
      */
 160  
     @Component
 161  
     private ArtifactMetadataSource metadataSource;
 162  
 
 163  
     /**
 164  
      * Determines how liberally the plugin will delete an artifact from the local repository. Values are: <br/>
 165  
      * <ul>
 166  
      * <li><b>file</b> - Eliminate only the artifact's file.</li>
 167  
      * <li><b>version</b> <i>(default)</i> - Eliminate all files associated with the version of the artifact.</li>
 168  
      * <li><b>artifactId</b> - Eliminate all files associated with the artifact's artifactId.</li>
 169  
      * <li><b>groupId</b> - Eliminate all files associated with the artifact's groupId.</li>
 170  
      * </ul>
 171  
      */
 172  
     @Parameter( property = "resolutionFuzziness", defaultValue = "version" )
 173  
     private String resolutionFuzziness;
 174  
 
 175  
     /**
 176  
      * Whether this mojo should act on all transitive dependencies. Default value is true.
 177  
      */
 178  
     @Parameter( property = "actTransitively", defaultValue = "true" )
 179  
     private boolean actTransitively;
 180  
 
 181  
     /**
 182  
      * Used to construct artifacts for deletion/resolution...
 183  
      */
 184  
     @Component
 185  
     private ArtifactFactory factory;
 186  
 
 187  
     /**
 188  
      * Whether this plugin should output verbose messages. Default is false.
 189  
      */
 190  
     @Parameter( property = "verbose", defaultValue = "false" )
 191  
     private boolean verbose;
 192  
 
 193  
     /**
 194  
      * Whether to purge only snapshot artifacts.
 195  
      * 
 196  
      * @since 2.4
 197  
      */
 198  
     @Parameter( property = "snapshotsOnly", defaultValue = "false" )
 199  
     private boolean snapshotsOnly;
 200  
 
 201  
     /**
 202  
      * Includes only direct project dependencies.
 203  
      */
 204  
     private class DirectDependencyFilter
 205  
         implements ArtifactFilter
 206  
     {
 207  
 
 208  
         private Artifact projectArtifact;
 209  
 
 210  
         private Set<Artifact> directDependencyArtifacts;
 211  
 
 212  
         /**
 213  
          * Default constructor
 214  
          * 
 215  
          * @param directDependencyArtifacts Set of Artifact objects which represent the direct dependencies of the
 216  
          *            project
 217  
          */
 218  
         public DirectDependencyFilter( Artifact projectArtifact, Set<Artifact> directDependencyArtifacts )
 219  0
         {
 220  0
             this.projectArtifact = projectArtifact;
 221  0
             this.directDependencyArtifacts = directDependencyArtifacts;
 222  0
         }
 223  
 
 224  
         public boolean include( Artifact artifact )
 225  
         {
 226  0
             if ( artifactsGAMatch( artifact, projectArtifact ) )
 227  
             {
 228  0
                 return true;
 229  
             }
 230  0
             for ( Artifact depArtifact : directDependencyArtifacts )
 231  
             {
 232  0
                 if ( this.artifactsGAMatch( artifact, depArtifact ) )
 233  
                 {
 234  0
                     return true;
 235  
                 }
 236  
             }
 237  0
             return false;
 238  
         }
 239  
 
 240  
         /*
 241  
          * Compare the groupId:artifactId of two artifacts.
 242  
          */
 243  
         private boolean artifactsGAMatch( Artifact artifact1, Artifact artifact2 )
 244  
         {
 245  0
             if ( artifact1 == artifact2 )
 246  
             {
 247  0
                 return true;
 248  
             }
 249  
 
 250  0
             if ( !artifact1.getGroupId().equals( artifact2.getGroupId() ) )
 251  
             {
 252  0
                 getLog().debug( "Different groupId: " + artifact1 + "  " + artifact2 );
 253  0
                 return false;
 254  
             }
 255  0
             if ( !artifact1.getArtifactId().equals( artifact2.getArtifactId() ) )
 256  
             {
 257  0
                 getLog().debug( "Different artifactId: " + artifact1 + "  " + artifact2 );
 258  0
                 return false;
 259  
             }
 260  0
             return true;
 261  
         }
 262  
     }
 263  
 
 264  
     /**
 265  
      * Includes only artifacts that do not use system scope
 266  
      */
 267  0
     private class SystemScopeExcludeFilter
 268  
         implements ArtifactFilter
 269  
     {
 270  
         public boolean include( Artifact artifact )
 271  
         {
 272  0
             return !Artifact.SCOPE_SYSTEM.equals( artifact.getScope() );
 273  
         }
 274  
     }
 275  
 
 276  
     /**
 277  
      * Includes only snapshot artifacts
 278  
      */
 279  0
     private class SnapshotsFilter
 280  
         implements ArtifactFilter
 281  
     {
 282  
         public boolean include( Artifact artifact )
 283  
         {
 284  0
             return artifact.isSnapshot();
 285  
         }
 286  
     }
 287  
 
 288  
     public void execute()
 289  
         throws MojoExecutionException, MojoFailureException
 290  
     {
 291  0
         if ( !StringUtils.isEmpty( manualInclude ) )
 292  
         {
 293  0
             manualIncludes = this.parseIncludes( manualInclude );
 294  
         }
 295  
         // If it's a manual purge, the only step is to delete from the local repo
 296  0
         if ( manualIncludes != null && manualIncludes.size() > 0 )
 297  
         {
 298  0
             manualPurge( manualIncludes );
 299  0
             return;
 300  
         }
 301  
 
 302  0
         Set<Artifact> dependencyArtifacts = null;
 303  
 
 304  
         try
 305  
         {
 306  0
             dependencyArtifacts = project.createArtifacts( factory, null, null );
 307  
         }
 308  0
         catch ( InvalidDependencyVersionException e )
 309  
         {
 310  0
             throw new MojoFailureException( "Unable to purge dependencies due to invalid dependency version ", e );
 311  0
         }
 312  
 
 313  0
         ArtifactFilter artifactFilter = createPurgeArtifactsFilter( dependencyArtifacts );
 314  
 
 315  0
         Set<Artifact> resolvedArtifactsToPurge =
 316  
             getFilteredResolvedArtifacts( project, dependencyArtifacts, artifactFilter );
 317  
 
 318  0
         if ( resolvedArtifactsToPurge.isEmpty() )
 319  
         {
 320  0
             getLog().info( "No artifacts included for purge for project: " + project.getId() );
 321  0
             return;
 322  
         }
 323  
 
 324  0
         verbose( "Purging dependencies for project: " + project.getId() );
 325  0
         purgeArtifacts( resolvedArtifactsToPurge );
 326  
 
 327  0
         if ( reResolve )
 328  
         {
 329  
             try
 330  
             {
 331  0
                 reResolveArtifacts( project, resolvedArtifactsToPurge, artifactFilter );
 332  
             }
 333  0
             catch ( ArtifactResolutionException e )
 334  
             {
 335  0
                 String failureMessage = "Failed to refresh project dependencies for: " + project.getId();
 336  0
                 MojoFailureException failure = new MojoFailureException( failureMessage );
 337  0
                 failure.initCause( e );
 338  
 
 339  0
                 throw failure;
 340  
             }
 341  0
             catch ( ArtifactNotFoundException e )
 342  
             {
 343  0
                 String failureMessage = "Failed to refresh project dependencies for: " + project.getId();
 344  0
                 MojoFailureException failure = new MojoFailureException( failureMessage );
 345  0
                 failure.initCause( e );
 346  
 
 347  0
                 throw failure;
 348  0
             }
 349  
         }
 350  0
     }
 351  
 
 352  
     /**
 353  
      * Purge/Delete artifacts from the local repository according to the given patterns.
 354  
      * 
 355  
      * @param inclusionPatterns
 356  
      * @throws MojoExecutionException
 357  
      */
 358  
     private void manualPurge( List<String> includes )
 359  
         throws MojoExecutionException
 360  
     {
 361  0
         for ( String gavPattern : includes )
 362  
         {
 363  0
             if ( StringUtils.isEmpty( gavPattern ) )
 364  
             {
 365  0
                 getLog().debug( "Skipping empty gav pattern: " + gavPattern );
 366  0
                 continue;
 367  
             }
 368  
 
 369  0
             String relativePath = gavToPath( gavPattern );
 370  0
             if ( StringUtils.isEmpty( relativePath ) )
 371  
             {
 372  0
                 continue;
 373  
             }
 374  
 
 375  0
             File purgeDir = new File( localRepository.getBasedir(), relativePath );
 376  0
             if ( purgeDir.exists() )
 377  
             {
 378  0
                 getLog().debug( "Deleting directory: " + purgeDir );
 379  
                 try
 380  
                 {
 381  0
                     FileUtils.deleteDirectory( purgeDir );
 382  
                 }
 383  0
                 catch ( IOException e )
 384  
                 {
 385  0
                     throw new MojoExecutionException( "Unable to purge directory: " + purgeDir );
 386  0
                 }
 387  
             }
 388  0
         }
 389  0
     }
 390  
 
 391  
     /**
 392  
      * Convert a groupId:artifactId:version to a file system path
 393  
      * 
 394  
      * @param gav, the groupId:artifactId:version string
 395  
      * @return
 396  
      */
 397  
     private String gavToPath( String gav )
 398  
     {
 399  0
         if ( StringUtils.isEmpty( gav ) )
 400  
         {
 401  0
             return null;
 402  
         }
 403  
 
 404  0
         String[] pathComponents = gav.split( ":" );
 405  
 
 406  0
         StringBuffer path = new StringBuffer( pathComponents[0].replace( '.', '/' ) );
 407  
 
 408  0
         for ( int i = 1; i < pathComponents.length; ++i )
 409  
         {
 410  0
             path.append( "/" + pathComponents[i] );
 411  
         }
 412  
 
 413  0
         return path.toString();
 414  
     }
 415  
 
 416  
     /**
 417  
      * Create the includes exclude filter to use when resolving and purging dependencies Also excludes any "system"
 418  
      * scope dependencies
 419  
      * 
 420  
      * @param dependencyArtifacts The dependency artifacts to use as a reference if we're excluding transitive
 421  
      *            dependencies
 422  
      * @return
 423  
      */
 424  
     private ArtifactFilter createPurgeArtifactsFilter( Set<Artifact> dependencyArtifacts )
 425  
     {
 426  0
         AndArtifactFilter andFilter = new AndArtifactFilter();
 427  
 
 428  
         // System dependencies should never be purged
 429  0
         andFilter.add( new SystemScopeExcludeFilter() );
 430  
 
 431  0
         if ( this.snapshotsOnly )
 432  
         {
 433  0
             andFilter.add( new SnapshotsFilter() );
 434  
         }
 435  
 
 436  
         // The CLI includes/excludes overrides configuration in the pom
 437  0
         if ( !StringUtils.isEmpty( this.include ) )
 438  
         {
 439  0
             this.includes = parseIncludes( this.include );
 440  
         }
 441  0
         if ( this.includes != null )
 442  
         {
 443  0
             andFilter.add( new PatternIncludesArtifactFilter( includes ) );
 444  
         }
 445  
 
 446  0
         if ( !StringUtils.isEmpty( this.exclude ) )
 447  
         {
 448  0
             this.excludes = parseIncludes( this.exclude );
 449  
         }
 450  0
         if ( this.excludes != null )
 451  
         {
 452  0
             andFilter.add( new PatternExcludesArtifactFilter( excludes ) );
 453  
         }
 454  
 
 455  0
         if ( !actTransitively )
 456  
         {
 457  0
             andFilter.add( new DirectDependencyFilter( project.getArtifact(), dependencyArtifacts ) );
 458  
         }
 459  
 
 460  0
         return andFilter;
 461  
     }
 462  
 
 463  
     /**
 464  
      * Convert comma separated list of includes to List object
 465  
      * 
 466  
      * @param include
 467  
      * @return the includes list
 468  
      */
 469  
     private List<String> parseIncludes( String include )
 470  
     {
 471  0
         List<String> includes = new ArrayList<String>();
 472  
 
 473  0
         if ( include != null )
 474  
         {
 475  0
             String[] elements = include.split( "," );
 476  0
             includes.addAll( Arrays.asList( elements ) );
 477  
         }
 478  
 
 479  0
         return includes;
 480  
     }
 481  
 
 482  
     private Set<Artifact> getFilteredResolvedArtifacts( MavenProject project, Set<Artifact> artifacts,
 483  
                                                         ArtifactFilter filter )
 484  
     {
 485  
         try
 486  
         {
 487  0
             ArtifactResolutionResult result =
 488  
                 resolver.resolveTransitively( artifacts, project.getArtifact(), localRepository, remoteRepositories,
 489  
                                               metadataSource, filter );
 490  
 
 491  
             @SuppressWarnings( "unchecked" )
 492  0
             Set<Artifact> resolvedArtifacts = result.getArtifacts();
 493  
 
 494  0
             return resolvedArtifacts;
 495  
         }
 496  0
         catch ( ArtifactResolutionException e )
 497  
         {
 498  0
             getLog().info( "Unable to resolve all dependencies for : " + e.getGroupId() + ":" + e.getArtifactId() + ":"
 499  
                                + e.getVersion()
 500  
                                + ". Falling back to non-transitive mode for initial artifact resolution." );
 501  
         }
 502  0
         catch ( ArtifactNotFoundException e )
 503  
         {
 504  0
             getLog().info( "Unable to resolve all dependencies for : " + e.getGroupId() + ":" + e.getArtifactId() + ":"
 505  
                                + e.getVersion()
 506  
                                + ". Falling back to non-transitive mode for initial artifact resolution." );
 507  0
         }
 508  
 
 509  0
         Set<Artifact> resolvedArtifacts = new LinkedHashSet<Artifact>();
 510  
         // Resolve the only poms here instead of the actual artifacts, because the files will be deleted during the
 511  
         // purge anyway
 512  0
         for ( Artifact artifact : artifacts )
 513  
         {
 514  0
             if ( filter.include( artifact ) )
 515  
             {
 516  
                 try
 517  
                 {
 518  0
                     resolvedArtifacts.add( artifact );
 519  0
                     resolver.resolve( artifact, remoteRepositories, localRepository );
 520  
                 }
 521  0
                 catch ( ArtifactResolutionException e )
 522  
                 {
 523  0
                     getLog().debug( "Unable to resolve artifact: " + artifact );
 524  
                 }
 525  0
                 catch ( ArtifactNotFoundException e )
 526  
                 {
 527  0
                     getLog().debug( "Unable to resolve artifact: " + artifact );
 528  0
                 }
 529  
             }
 530  
         }
 531  0
         return resolvedArtifacts;
 532  
     }
 533  
 
 534  
     private void purgeArtifacts( Set<Artifact> artifacts )
 535  
         throws MojoFailureException
 536  
     {
 537  0
         for ( Artifact artifact : artifacts )
 538  
         {
 539  0
             verbose( "Purging artifact: " + artifact.getId() );
 540  
 
 541  0
             File deleteTarget = findDeleteTarget( artifact );
 542  
 
 543  0
             verbose( "Deleting: " + deleteTarget );
 544  
 
 545  0
             if ( deleteTarget.isDirectory() )
 546  
             {
 547  
                 try
 548  
                 {
 549  0
                     FileUtils.deleteDirectory( deleteTarget );
 550  
                 }
 551  0
                 catch ( IOException e )
 552  
                 {
 553  0
                     getLog().warn( "Unable to purge local repository location: " + deleteTarget, e );
 554  0
                 }
 555  
             }
 556  
             else
 557  
             {
 558  0
                 if ( !deleteTarget.delete() )
 559  
                 {
 560  0
                     getLog().warn( "Unable to purge local repository location: " + deleteTarget );
 561  
                 }
 562  
             }
 563  0
             artifact.setResolved( false );
 564  0
         }
 565  0
     }
 566  
 
 567  
     private void reResolveArtifacts( MavenProject project, Set<Artifact> artifacts, ArtifactFilter filter )
 568  
         throws ArtifactResolutionException, ArtifactNotFoundException
 569  
     {
 570  
 
 571  
         // Always need to re-resolve the poms in case they were purged along with the artifact
 572  
         // because Maven 2 will not automatically re-resolve them when resolving the artifact
 573  0
         for ( Artifact artifact : artifacts )
 574  
         {
 575  
             try
 576  
             {
 577  0
                 Artifact pomArtifact =
 578  
                     factory.createArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(),
 579  
                                             null, "pom" );
 580  0
                 resolver.resolveAlways( pomArtifact, remoteRepositories, localRepository );
 581  
             }
 582  0
             catch ( ArtifactResolutionException e )
 583  
             {
 584  0
                 verbose( e.getMessage() );
 585  
             }
 586  0
             catch ( ArtifactNotFoundException e )
 587  
             {
 588  0
                 verbose( e.getMessage() );
 589  0
             }
 590  
         }
 591  
 
 592  0
         List<Artifact> missingArtifacts = new ArrayList<Artifact>();
 593  
 
 594  0
         for ( Artifact artifact : artifacts )
 595  
         {
 596  0
             verbose( "Resolving artifact: " + artifact.getId() );
 597  
 
 598  
             try
 599  
             {
 600  0
                 resolver.resolveAlways( artifact, project.getRemoteArtifactRepositories(), localRepository );
 601  
             }
 602  0
             catch ( ArtifactResolutionException e )
 603  
             {
 604  0
                 verbose( e.getMessage() );
 605  0
                 missingArtifacts.add( artifact );
 606  
             }
 607  0
             catch ( ArtifactNotFoundException e )
 608  
             {
 609  0
                 verbose( e.getMessage() );
 610  0
                 missingArtifacts.add( artifact );
 611  0
             }
 612  
         }
 613  
 
 614  0
         if ( missingArtifacts.size() > 0 )
 615  
         {
 616  0
             String message = "required artifacts missing:\n";
 617  0
             for ( Artifact missingArtifact : missingArtifacts )
 618  
             {
 619  0
                 message += "  " + missingArtifact.getId() + "\n";
 620  
             }
 621  0
             message += "\nfor the artifact:";
 622  
 
 623  0
             throw new ArtifactResolutionException( message, project.getArtifact(),
 624  
                                                    project.getRemoteArtifactRepositories() );
 625  
         }
 626  0
     }
 627  
 
 628  
     private File findDeleteTarget( Artifact artifact )
 629  
     {
 630  
         // Use localRepository.pathOf() in case artifact.getFile() is not set
 631  0
         File deleteTarget = new File( localRepository.getBasedir(), localRepository.pathOf( artifact ) );
 632  
 
 633  0
         if ( GROUP_ID_FUZZINESS.equals( resolutionFuzziness ) )
 634  
         {
 635  
             // get the groupId dir.
 636  0
             deleteTarget = deleteTarget.getParentFile().getParentFile().getParentFile();
 637  
         }
 638  0
         else if ( ARTIFACT_ID_FUZZINESS.equals( resolutionFuzziness ) )
 639  
         {
 640  
             // get the artifactId dir.
 641  0
             deleteTarget = deleteTarget.getParentFile().getParentFile();
 642  
         }
 643  0
         else if ( VERSION_FUZZINESS.equals( resolutionFuzziness ) )
 644  
         {
 645  
             // get the version dir.
 646  0
             deleteTarget = deleteTarget.getParentFile();
 647  
         }
 648  
         // else it's file fuzziness.
 649  0
         return deleteTarget;
 650  
     }
 651  
 
 652  
     private void verbose( String message )
 653  
     {
 654  0
         if ( verbose || getLog().isDebugEnabled() )
 655  
         {
 656  0
             getLog().info( message );
 657  
         }
 658  0
     }
 659  
 
 660  
 }