Coverage Report - org.apache.maven.artifact.resolver.DefaultArtifactCollector
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultArtifactCollector
71 %
147/207
64 %
93/146
8,444
 
 1  
 package org.apache.maven.artifact.resolver;
 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.metadata.ArtifactMetadataRetrievalException;
 24  
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
 25  
 import org.apache.maven.artifact.metadata.ResolutionGroup;
 26  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 27  
 import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
 28  
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 29  
 import org.apache.maven.artifact.versioning.ArtifactVersion;
 30  
 import org.apache.maven.artifact.versioning.ManagedVersionMap;
 31  
 import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
 32  
 import org.apache.maven.artifact.versioning.VersionRange;
 33  
 
 34  
 import java.util.ArrayList;
 35  
 import java.util.Collections;
 36  
 import java.util.Iterator;
 37  
 import java.util.LinkedHashMap;
 38  
 import java.util.LinkedHashSet;
 39  
 import java.util.List;
 40  
 import java.util.Map;
 41  
 import java.util.Set;
 42  
 
 43  
 /**
 44  
  * Default implementation of the artifact collector.
 45  
  *
 46  
  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 47  
  * @version $Id: DefaultArtifactCollector.java 801437 2009-08-05 22:06:54Z jdcasey $
 48  
  */
 49  33
 public class DefaultArtifactCollector
 50  
     implements ArtifactCollector
 51  
 {
 52  
     public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact,
 53  
                                              ArtifactRepository localRepository, List remoteRepositories,
 54  
                                              ArtifactMetadataSource source, ArtifactFilter filter, List listeners )
 55  
         throws ArtifactResolutionException
 56  
     {
 57  111
         return collect( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories,
 58  
                         source, filter, listeners );
 59  
     }
 60  
 
 61  
     public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, Map managedVersions,
 62  
                                              ArtifactRepository localRepository, List remoteRepositories,
 63  
                                              ArtifactMetadataSource source, ArtifactFilter filter, List listeners )
 64  
         throws ArtifactResolutionException
 65  
     {
 66  114
         Map resolvedArtifacts = new LinkedHashMap();
 67  
 
 68  114
         ResolutionNode root = new ResolutionNode( originatingArtifact, remoteRepositories );
 69  
 
 70  114
         root.addDependencies( artifacts, remoteRepositories, filter );
 71  
 
 72  114
         ManagedVersionMap versionMap = getManagedVersionsMap( originatingArtifact, managedVersions );
 73  
 
 74  114
         recurse( originatingArtifact, root, resolvedArtifacts, versionMap, localRepository, remoteRepositories, source, filter,
 75  
                  listeners );
 76  
 
 77  110
         Set set = new LinkedHashSet();
 78  
 
 79  110
         for ( Iterator i = resolvedArtifacts.values().iterator(); i.hasNext(); )
 80  
         {
 81  511
             List nodes = (List) i.next();
 82  511
             for ( Iterator j = nodes.iterator(); j.hasNext(); )
 83  
             {
 84  651
                 ResolutionNode node = (ResolutionNode) j.next();
 85  651
                 if ( !node.equals( root ) && node.isActive() )
 86  
                 {
 87  400
                     Artifact artifact = node.getArtifact();
 88  
 
 89  400
                     if ( node.filterTrail( filter ) )
 90  
                     {
 91  
                         // If it was optional and not a direct dependency,
 92  
                         // we don't add it or its children, just allow the update of the version and scope
 93  392
                         if ( node.isChildOfRootNode() || !artifact.isOptional() )
 94  
                         {
 95  392
                             artifact.setDependencyTrail( node.getDependencyTrail() );
 96  
 
 97  392
                             set.add( node );
 98  
                         }
 99  
                     }
 100  
                 }
 101  651
             }
 102  511
         }
 103  
 
 104  110
         ArtifactResolutionResult result = new ArtifactResolutionResult();
 105  110
         result.setArtifactResolutionNodes( set );
 106  110
         return result;
 107  
     }
 108  
 
 109  
     /**
 110  
      * Get the map of managed versions, removing the originating artifact if it is also in managed versions
 111  
      * @param originatingArtifact artifact we are processing
 112  
      * @param managedVersions original managed versions
 113  
      */
 114  
     private ManagedVersionMap getManagedVersionsMap( Artifact originatingArtifact, Map managedVersions )
 115  
     {
 116  
         ManagedVersionMap versionMap;
 117  114
         if ( managedVersions != null && managedVersions instanceof ManagedVersionMap )
 118  
         {
 119  0
             versionMap = (ManagedVersionMap) managedVersions;
 120  
         }
 121  
         else
 122  
         {
 123  114
             versionMap = new ManagedVersionMap( managedVersions );
 124  
         }
 125  
 
 126  
         /* remove the originating artifact if it is also in managed versions to avoid being modified during resolution */
 127  114
         Artifact managedOriginatingArtifact = (Artifact) versionMap.get( originatingArtifact.getDependencyConflictId() );
 128  114
         if ( managedOriginatingArtifact != null )
 129  
         {
 130  
             // TODO we probably want to warn the user that he is building an artifact with
 131  
             // different values than in dependencyManagement
 132  1
             if ( managedVersions instanceof ManagedVersionMap )
 133  
             {
 134  
                 /* avoid modifying the managedVersions parameter creating a new map */
 135  0
                 versionMap = new ManagedVersionMap( managedVersions );
 136  
             }
 137  1
             versionMap.remove( originatingArtifact.getDependencyConflictId() );
 138  
         }
 139  
 
 140  114
         return versionMap;
 141  
     }
 142  
 
 143  
     private void recurse( Artifact originatingArtifact, ResolutionNode node, Map resolvedArtifacts, ManagedVersionMap managedVersions,
 144  
                           ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source,
 145  
                           ArtifactFilter filter, List listeners )
 146  
         throws CyclicDependencyException, ArtifactResolutionException, OverConstrainedVersionException
 147  
     {
 148  661
         fireEvent( ResolutionListener.TEST_ARTIFACT, listeners, node );
 149  
 
 150  661
         Object key = node.getKey();
 151  
 
 152  
         // TODO: Does this check need to happen here?  Had to add the same call
 153  
         // below when we iterate on child nodes -- will that suffice?
 154  661
         if ( managedVersions.containsKey( key ))
 155  
         {
 156  2
             manageArtifact( node, managedVersions, listeners );
 157  
         }
 158  
 
 159  661
         List previousNodes = (List) resolvedArtifacts.get( key );
 160  661
         if ( previousNodes != null )
 161  
         {
 162  140
             for ( Iterator i = previousNodes.iterator(); i.hasNext(); )
 163  
             {
 164  180
                 ResolutionNode previous = (ResolutionNode) i.next();
 165  
 
 166  180
                 if ( previous.isActive() )
 167  
                 {
 168  
                     // Version mediation
 169  140
                     VersionRange previousRange = previous.getArtifact().getVersionRange();
 170  140
                     VersionRange currentRange = node.getArtifact().getVersionRange();
 171  
 
 172  140
                     if ( previousRange != null && currentRange != null )
 173  
                     {
 174  
                         // TODO: shouldn't need to double up on this work, only done for simplicity of handling recommended
 175  
                         // version but the restriction is identical
 176  140
                         VersionRange newRange = previousRange.restrict( currentRange );
 177  
                         // TODO: ick. this forces the OCE that should have come from the previous call. It is still correct
 178  140
                         if ( newRange.isSelectedVersionKnown( previous.getArtifact() ) )
 179  
                         {
 180  135
                             fireEvent( ResolutionListener.RESTRICT_RANGE, listeners, node, previous.getArtifact(),
 181  
                                        newRange );
 182  
                         }
 183  140
                         previous.getArtifact().setVersionRange( newRange );
 184  140
                         node.getArtifact().setVersionRange( currentRange.restrict( previousRange ) );
 185  
 
 186  
                         //Select an appropriate available version from the (now restricted) range
 187  
                         //Note this version was selected before to get the appropriate POM
 188  
                         //But it was reset by the call to setVersionRange on restricting the version
 189  140
                         ResolutionNode[] resetNodes = {previous, node};
 190  420
                         for ( int j = 0; j < 2; j++ )
 191  
                         {
 192  280
                             Artifact resetArtifact = resetNodes[j].getArtifact();
 193  
 
 194  
                             //MNG-2123: if the previous node was not a range, then it wouldn't have any available
 195  
                             //versions. We just clobbered the selected version above. (why? i have no idea.)
 196  
                             //So since we are here and this is ranges we must go figure out the version (for a third time...)
 197  280
                             if ( resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null )
 198  
                             {
 199  
 
 200  
                                 // go find the version. This is a total hack. See previous comment.
 201  10
                                 List versions = resetArtifact.getAvailableVersions();
 202  10
                                 if ( versions == null )
 203  
                                 {
 204  
                                     try
 205  
                                     {
 206  4
                                         versions =
 207  
                                             source.retrieveAvailableVersions( resetArtifact, localRepository,
 208  
                                                                               remoteRepositories );
 209  4
                                         resetArtifact.setAvailableVersions( versions );
 210  
                                     }
 211  0
                                     catch ( ArtifactMetadataRetrievalException e )
 212  
                                     {
 213  0
                                         resetArtifact.setDependencyTrail( node.getDependencyTrail() );
 214  0
                                         throw new ArtifactResolutionException(
 215  
                                                                                "Unable to get dependency information: " +
 216  
                                                                                    e.getMessage(), resetArtifact,
 217  
                                                                                remoteRepositories, e );
 218  4
                                     }
 219  
                                 }
 220  
                                 //end hack
 221  
 
 222  
                                 //MNG-2861: match version can return null
 223  10
                                 ArtifactVersion selectedVersion = resetArtifact.getVersionRange().matchVersion( resetArtifact.getAvailableVersions() );
 224  10
                                 if (selectedVersion != null)
 225  
                                 {
 226  10
                                   resetArtifact.selectVersion( selectedVersion.toString() );
 227  
                                 }
 228  
                                 else
 229  
                                 {
 230  0
                                   throw new OverConstrainedVersionException(" Unable to find a version in "+ resetArtifact.getAvailableVersions()+" to match the range "+ resetArtifact.getVersionRange(), resetArtifact);
 231  
                                 }
 232  
 
 233  10
                                 fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, resetNodes[j] );
 234  
                             }
 235  
                         }
 236  
                     }
 237  
 
 238  
                     // Conflict Resolution
 239  
                     // TODO: use as conflict resolver(s), chain
 240  
 
 241  
                     // TODO: should this be part of mediation?
 242  
                     // previous one is more dominant
 243  
                     ResolutionNode nearest;
 244  
                     ResolutionNode farthest;
 245  140
                     if ( previous.getDepth() <= node.getDepth() )
 246  
                     {
 247  10
                         nearest = previous;
 248  10
                         farthest = node;
 249  
                     }
 250  
                     else
 251  
                     {
 252  130
                         nearest = node;
 253  130
                         farthest = previous;
 254  
                     }
 255  
 
 256  140
                     if ( checkScopeUpdate( farthest, nearest, listeners ) )
 257  
                     {
 258  
                         // if we need to update scope of nearest to use farthest scope, use the nearest version, but farthest scope
 259  19
                         nearest.disable();
 260  19
                         farthest.getArtifact().setVersion( nearest.getArtifact().getVersion() );
 261  19
                         fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, nearest, farthest.getArtifact() );
 262  
                     }
 263  
                     else
 264  
                     {
 265  121
                         farthest.disable();
 266  121
                         fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, farthest, nearest.getArtifact() );
 267  
                     }
 268  
                 }
 269  180
             }
 270  
         }
 271  
         else
 272  
         {
 273  521
             previousNodes = new ArrayList();
 274  521
             resolvedArtifacts.put( key, previousNodes );
 275  
         }
 276  661
         previousNodes.add( node );
 277  
 
 278  661
         if ( node.isActive() )
 279  
         {
 280  632
             fireEvent( ResolutionListener.INCLUDE_ARTIFACT, listeners, node );
 281  
         }
 282  
 
 283  
         // don't pull in the transitive deps of a system-scoped dependency.
 284  661
         if ( node.isActive() && !Artifact.SCOPE_SYSTEM.equals( node.getArtifact().getScope() ) )
 285  
         {
 286  608
             fireEvent( ResolutionListener.PROCESS_CHILDREN, listeners, node );
 287  
 
 288  608
             Artifact parentArtifact = node.getArtifact();
 289  
             
 290  608
             for ( Iterator i = node.getChildrenIterator(); i.hasNext(); )
 291  
             {
 292  552
                 ResolutionNode child = (ResolutionNode) i.next();
 293  
 
 294  
                 // We leave in optional ones, but don't pick up its dependencies
 295  552
                 if ( !child.isResolved() && ( !child.getArtifact().isOptional() || child.isChildOfRootNode() ) )
 296  
                 {
 297  551
                     Artifact artifact = child.getArtifact();
 298  551
                     artifact.setDependencyTrail( node.getDependencyTrail() );
 299  
                     
 300  551
                     List childRemoteRepositories = child.getRemoteRepositories();
 301  
                     try
 302  
                     {
 303  
                         Object childKey;
 304  
                         do
 305  
                         {
 306  551
                             childKey = child.getKey();
 307  
 
 308  551
                             if ( managedVersions.containsKey( childKey ) )
 309  
                             {
 310  
                                 // If this child node is a managed dependency, ensure
 311  
                                 // we are using the dependency management version
 312  
                                 // of this child if applicable b/c we want to use the
 313  
                                 // managed version's POM, *not* any other version's POM.
 314  
                                 // We retrieve the POM below in the retrieval step.
 315  2
                                 manageArtifact( child, managedVersions, listeners );
 316  
 
 317  
                                 // Also, we need to ensure that any exclusions it presents are
 318  
                                 // added to the artifact before we retrieve the metadata
 319  
                                 // for the artifact; otherwise we may end up with unwanted
 320  
                                 // dependencies.
 321  2
                                 Artifact ma = (Artifact) managedVersions.get( childKey );
 322  2
                                 ArtifactFilter managedExclusionFilter = ma.getDependencyFilter();
 323  2
                                 if ( null != managedExclusionFilter )
 324  
                                 {
 325  0
                                     if ( null != artifact.getDependencyFilter() )
 326  
                                     {
 327  0
                                         AndArtifactFilter aaf = new AndArtifactFilter();
 328  0
                                         aaf.add( artifact.getDependencyFilter() );
 329  0
                                         aaf.add( managedExclusionFilter );
 330  0
                                         artifact.setDependencyFilter( aaf );
 331  0
                                     }
 332  
                                     else
 333  
                                     {
 334  0
                                         artifact.setDependencyFilter( managedExclusionFilter );
 335  
                                     }
 336  
                                 }
 337  
                             }
 338  
 
 339  551
                             if ( artifact.getVersion() == null )
 340  
                             {
 341  
                                 // set the recommended version
 342  
                                 // TODO: maybe its better to just pass the range through to retrieval and use a transformation?
 343  
                                 ArtifactVersion version;
 344  13
                                 if ( artifact.isSelectedVersionKnown() )
 345  
                                 {
 346  0
                                     version = artifact.getSelectedVersion();
 347  
                                 }
 348  
                                 else
 349  
                                 {
 350  
                                     //go find the version
 351  13
                                     List versions = artifact.getAvailableVersions();
 352  13
                                     if ( versions == null )
 353  
                                     {
 354  13
                                         versions = source.retrieveAvailableVersions( artifact, localRepository,
 355  
                                                                                      childRemoteRepositories );
 356  13
                                         artifact.setAvailableVersions( versions );
 357  
                                     }
 358  
 
 359  13
                                     Collections.sort( versions );
 360  
 
 361  13
                                     VersionRange versionRange = artifact.getVersionRange();
 362  
 
 363  13
                                     version = versionRange.matchVersion( versions );
 364  
 
 365  13
                                     if ( version == null )
 366  
                                     {
 367  4
                                         if ( versions.isEmpty() )
 368  
                                         {
 369  2
                                             throw new OverConstrainedVersionException(
 370  
                                                 "No versions are present in the repository for the artifact with a range " +
 371  
                                                     versionRange, artifact, childRemoteRepositories );
 372  
                                         }
 373  
 
 374  2
                                         throw new OverConstrainedVersionException( "Couldn't find a version in " +
 375  
                                             versions + " to match range " + versionRange, artifact,
 376  
                                             childRemoteRepositories );
 377  
                                     }
 378  
                                 }
 379  
 
 380  
                                 //this is dangerous because artifact.getSelectedVersion() can
 381  
                                 //return null. However it is ok here because we first check if the
 382  
                                 //selected version is known. As currently coded we can't get a null here.
 383  9
                                 artifact.selectVersion( version.toString() );
 384  9
                                 fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, child );
 385  
                             }
 386  
 
 387  547
                             Artifact relocated = source.retrieveRelocatedArtifact( artifact, localRepository, childRemoteRepositories );
 388  547
                             if ( relocated != null && !artifact.equals( relocated ) )
 389  
                             {
 390  0
                                 relocated.setDependencyFilter( artifact.getDependencyFilter() );
 391  0
                                 artifact = relocated;
 392  0
                                 child.setArtifact( artifact );
 393  
                             }
 394  
                         }
 395  547
                         while( !childKey.equals( child.getKey() ) );
 396  
                         
 397  547
                         if ( parentArtifact != null && parentArtifact.getDependencyFilter() != null && !parentArtifact.getDependencyFilter().include( artifact ) )
 398  
                         {
 399  
                             // MNG-3769: the [probably relocated] artifact is excluded. 
 400  
                             // We could process exclusions on relocated artifact details in the
 401  
                             // MavenMetadataSource.createArtifacts(..) step, BUT that would
 402  
                             // require resolving the POM from the repository very early on in
 403  
                             // the build.
 404  0
                             continue;
 405  
                         }
 406  
 
 407  547
                         ResolutionGroup rGroup = source.retrieve( artifact, localRepository, childRemoteRepositories );
 408  
 
 409  
                         //TODO might be better to have source.retrieve() throw a specific exception for this situation
 410  
                         //and catch here rather than have it return null
 411  547
                         if ( rGroup == null )
 412  
                         {
 413  
                             //relocated dependency artifact is declared excluded, no need to add and recurse further
 414  0
                             continue;
 415  
                         }
 416  
 
 417  547
                         child.addDependencies( rGroup.getArtifacts(), rGroup.getResolutionRepositories(), filter );
 418  
 
 419  
                     }
 420  0
                     catch ( CyclicDependencyException e )
 421  
                     {
 422  
                         // would like to throw this, but we have crappy stuff in the repo
 423  
 
 424  0
                         fireEvent( ResolutionListener.OMIT_FOR_CYCLE, listeners,
 425  
                                    new ResolutionNode( e.getArtifact(), childRemoteRepositories, child ) );
 426  
                     }
 427  0
                     catch ( ArtifactMetadataRetrievalException e )
 428  
                     {
 429  0
                         artifact.setDependencyTrail( node.getDependencyTrail() );
 430  0
                         throw new ArtifactResolutionException(
 431  
                             "Unable to get dependency information: " + e.getMessage(), artifact, childRemoteRepositories,
 432  
                             e );
 433  547
                     }
 434  
 
 435  547
                     recurse( originatingArtifact, child, resolvedArtifacts, managedVersions, localRepository, childRemoteRepositories, source,
 436  
                              filter, listeners );
 437  
                 }
 438  544
             }
 439  
 
 440  600
             fireEvent( ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node );
 441  
         }
 442  653
     }
 443  
 
 444  
     private void manageArtifact( ResolutionNode node, ManagedVersionMap managedVersions, List listeners )
 445  
     {
 446  4
         Artifact artifact = (Artifact) managedVersions.get( node.getKey() );
 447  
 
 448  
         // Before we update the version of the artifact, we need to know
 449  
         // whether we are working on a transitive dependency or not.  This
 450  
         // allows depMgmt to always override transitive dependencies, while
 451  
         // explicit child override depMgmt (viz. depMgmt should only
 452  
         // provide defaults to children, but should override transitives).
 453  
         // We can do this by calling isChildOfRootNode on the current node.
 454  
 
 455  4
         if ( artifact.getVersion() != null
 456  
                         && ( node.isChildOfRootNode() ? node.getArtifact().getVersion() == null : true ) )
 457  
         {
 458  4
             fireEvent( ResolutionListener.MANAGE_ARTIFACT_VERSION, listeners, node, artifact );
 459  4
             node.getArtifact().setVersion( artifact.getVersion() );
 460  
         }
 461  
 
 462  4
         if ( artifact.getScope() != null
 463  
                         && ( node.isChildOfRootNode() ? node.getArtifact().getScope() == null : true ) )
 464  
         {
 465  4
             fireEvent( ResolutionListener.MANAGE_ARTIFACT_SCOPE, listeners, node, artifact );
 466  4
             node.getArtifact().setScope( artifact.getScope() );
 467  
         }
 468  4
     }
 469  
 
 470  
     /**
 471  
      * Check if the scope needs to be updated.
 472  
      * <a href="http://docs.codehaus.org/x/IGU#DependencyMediationandConflictResolution-Scoperesolution">More info</a>.
 473  
      *
 474  
      * @param farthest  farthest resolution node
 475  
      * @param nearest   nearest resolution node
 476  
      * @param listeners
 477  
      */
 478  
     boolean checkScopeUpdate( ResolutionNode farthest, ResolutionNode nearest, List listeners )
 479  
     {
 480  140
         boolean updateScope = false;
 481  140
         Artifact farthestArtifact = farthest.getArtifact();
 482  140
         Artifact nearestArtifact = nearest.getArtifact();
 483  
 
 484  
         /* farthest is runtime and nearest has lower priority, change to runtime */
 485  140
         if ( Artifact.SCOPE_RUNTIME.equals( farthestArtifact.getScope() ) && (
 486  
             Artifact.SCOPE_TEST.equals( nearestArtifact.getScope() ) ||
 487  
                 Artifact.SCOPE_PROVIDED.equals( nearestArtifact.getScope() ) ) )
 488  
         {
 489  8
             updateScope = true;
 490  
         }
 491  
 
 492  
         /* farthest is compile and nearest is not (has lower priority), change to compile */
 493  140
         if ( Artifact.SCOPE_COMPILE.equals( farthestArtifact.getScope() ) &&
 494  
             !Artifact.SCOPE_COMPILE.equals( nearestArtifact.getScope() ) )
 495  
         {
 496  17
             updateScope = true;
 497  
         }
 498  
 
 499  
         /* current POM rules all, if nearest is in current pom, do not update its scope */
 500  140
         if ( nearest.getDepth() < 2 && updateScope )
 501  
         {
 502  6
             updateScope = false;
 503  
 
 504  6
             fireEvent( ResolutionListener.UPDATE_SCOPE_CURRENT_POM, listeners, nearest, farthestArtifact );
 505  
         }
 506  
 
 507  140
         if ( updateScope )
 508  
         {
 509  19
             fireEvent( ResolutionListener.UPDATE_SCOPE, listeners, nearest, farthestArtifact );
 510  
 
 511  
             // previously we cloned the artifact, but it is more effecient to just update the scope
 512  
             // if problems are later discovered that the original object needs its original scope value, cloning may
 513  
             // again be appropriate
 514  19
             nearestArtifact.setScope( farthestArtifact.getScope() );
 515  
         }
 516  
 
 517  140
         return updateScope;
 518  
     }
 519  
 
 520  
     private void fireEvent( int event, List listeners, ResolutionNode node )
 521  
     {
 522  2520
         fireEvent( event, listeners, node, null );
 523  2520
     }
 524  
 
 525  
     private void fireEvent( int event, List listeners, ResolutionNode node, Artifact replacement )
 526  
     {
 527  2693
         fireEvent( event, listeners, node, replacement, null );
 528  2693
     }
 529  
 
 530  
     private void fireEvent( int event, List listeners, ResolutionNode node, Artifact replacement,
 531  
                             VersionRange newRange )
 532  
     {
 533  2828
         for ( Iterator i = listeners.iterator(); i.hasNext(); )
 534  
         {
 535  0
             ResolutionListener listener = (ResolutionListener) i.next();
 536  
 
 537  0
             switch ( event )
 538  
             {
 539  
                 case ResolutionListener.TEST_ARTIFACT:
 540  0
                     listener.testArtifact( node.getArtifact() );
 541  0
                     break;
 542  
                 case ResolutionListener.PROCESS_CHILDREN:
 543  0
                     listener.startProcessChildren( node.getArtifact() );
 544  0
                     break;
 545  
                 case ResolutionListener.FINISH_PROCESSING_CHILDREN:
 546  0
                     listener.endProcessChildren( node.getArtifact() );
 547  0
                     break;
 548  
                 case ResolutionListener.INCLUDE_ARTIFACT:
 549  0
                     listener.includeArtifact( node.getArtifact() );
 550  0
                     break;
 551  
                 case ResolutionListener.OMIT_FOR_NEARER:
 552  0
                     listener.omitForNearer( node.getArtifact(), replacement );
 553  0
                     break;
 554  
                 case ResolutionListener.OMIT_FOR_CYCLE:
 555  0
                     listener.omitForCycle( node.getArtifact() );
 556  0
                     break;
 557  
                 case ResolutionListener.UPDATE_SCOPE:
 558  0
                     listener.updateScope( node.getArtifact(), replacement.getScope() );
 559  0
                     break;
 560  
                 case ResolutionListener.UPDATE_SCOPE_CURRENT_POM:
 561  0
                     listener.updateScopeCurrentPom( node.getArtifact(), replacement.getScope() );
 562  0
                     break;
 563  
                 case ResolutionListener.MANAGE_ARTIFACT_VERSION:
 564  0
                     if (listener instanceof ResolutionListenerForDepMgmt) {
 565  0
                         ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
 566  0
                         asImpl.manageArtifactVersion( node.getArtifact(), replacement );
 567  0
                     } else {
 568  0
                         listener.manageArtifact( node.getArtifact(), replacement );
 569  
                     }
 570  0
                     break;
 571  
                 case ResolutionListener.MANAGE_ARTIFACT_SCOPE:
 572  0
                     if (listener instanceof ResolutionListenerForDepMgmt) {
 573  0
                         ResolutionListenerForDepMgmt asImpl = (ResolutionListenerForDepMgmt) listener;
 574  0
                         asImpl.manageArtifactScope( node.getArtifact(), replacement );
 575  0
                     } else {
 576  0
                         listener.manageArtifact( node.getArtifact(), replacement );
 577  
                     }
 578  0
                     break;
 579  
                 case ResolutionListener.SELECT_VERSION_FROM_RANGE:
 580  0
                     listener.selectVersionFromRange( node.getArtifact() );
 581  0
                     break;
 582  
                 case ResolutionListener.RESTRICT_RANGE:
 583  0
                     if ( node.getArtifact().getVersionRange().hasRestrictions() ||
 584  
                         replacement.getVersionRange().hasRestrictions() )
 585  
                     {
 586  0
                         listener.restrictRange( node.getArtifact(), replacement, newRange );
 587  
                     }
 588  
                     break;
 589  
                 default:
 590  0
                     throw new IllegalStateException( "Unknown event: " + event );
 591  
             }
 592  0
         }
 593  2828
     }
 594  
 
 595  
 }