1 package org.apache.maven.artifact.resolver; 2 3 18 19 import org.apache.maven.artifact.Artifact; 20 import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; 21 import org.apache.maven.artifact.metadata.ArtifactMetadataSource; 22 import org.apache.maven.artifact.metadata.ResolutionGroup; 23 import org.apache.maven.artifact.repository.ArtifactRepository; 24 import org.apache.maven.artifact.resolver.filter.ArtifactFilter; 25 import org.apache.maven.artifact.versioning.ArtifactVersion; 26 import org.apache.maven.artifact.versioning.OverConstrainedVersionException; 27 import org.apache.maven.artifact.versioning.VersionRange; 28 29 import java.util.ArrayList ; 30 import java.util.Collections ; 31 import java.util.HashMap ; 32 import java.util.HashSet ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.Set ; 37 38 44 public class DefaultArtifactCollector 45 implements ArtifactCollector 46 { 47 public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, 48 ArtifactRepository localRepository, List remoteRepositories, 49 ArtifactMetadataSource source, ArtifactFilter filter, List listeners ) 50 throws ArtifactResolutionException 51 { 52 return collect( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories, 53 source, filter, listeners ); 54 } 55 56 public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, Map managedVersions, 57 ArtifactRepository localRepository, List remoteRepositories, 58 ArtifactMetadataSource source, ArtifactFilter filter, List listeners ) 59 throws ArtifactResolutionException 60 { 61 Map resolvedArtifacts = new HashMap (); 62 63 ResolutionNode root = new ResolutionNode( originatingArtifact, remoteRepositories ); 64 65 root.addDependencies( artifacts, remoteRepositories, filter ); 66 67 recurse( root, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter, 68 listeners ); 69 70 Set set = new HashSet (); 71 72 for ( Iterator i = resolvedArtifacts.values().iterator(); i.hasNext(); ) 73 { 74 List nodes = (List ) i.next(); 75 for ( Iterator j = nodes.iterator(); j.hasNext(); ) 76 { 77 ResolutionNode node = (ResolutionNode) j.next(); 78 if ( !node.equals( root ) && node.isActive() ) 79 { 80 Artifact artifact = node.getArtifact(); 81 82 if ( node.filterTrail( filter ) ) 83 { 84 if ( node.isChildOfRootNode() || !artifact.isOptional() ) 87 { 88 artifact.setDependencyTrail( node.getDependencyTrail() ); 89 90 set.add( node ); 91 } 92 } 93 } 94 } 95 } 96 97 ArtifactResolutionResult result = new ArtifactResolutionResult(); 98 result.setArtifactResolutionNodes( set ); 99 return result; 100 } 101 102 private void recurse( ResolutionNode node, Map resolvedArtifacts, Map managedVersions, 103 ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source, 104 ArtifactFilter filter, List listeners ) 105 throws CyclicDependencyException, ArtifactResolutionException, OverConstrainedVersionException 106 { 107 fireEvent( ResolutionListener.TEST_ARTIFACT, listeners, node ); 108 109 Object key = node.getKey(); 111 if ( managedVersions.containsKey( key ) ) 112 { 113 Artifact artifact = (Artifact) managedVersions.get( key ); 114 115 fireEvent( ResolutionListener.MANAGE_ARTIFACT, listeners, node, artifact ); 116 117 if ( artifact.getVersion() != null ) 118 { 119 node.getArtifact().setVersion( artifact.getVersion() ); 120 } 121 if ( artifact.getScope() != null ) 122 { 123 node.getArtifact().setScope( artifact.getScope() ); 124 } 125 } 126 127 List previousNodes = (List ) resolvedArtifacts.get( key ); 128 if ( previousNodes != null ) 129 { 130 for ( Iterator i = previousNodes.iterator(); i.hasNext(); ) 131 { 132 ResolutionNode previous = (ResolutionNode) i.next(); 133 134 if ( previous.isActive() ) 135 { 136 VersionRange previousRange = previous.getArtifact().getVersionRange(); 138 VersionRange currentRange = node.getArtifact().getVersionRange(); 139 140 if ( previousRange != null && currentRange != null ) 141 { 142 VersionRange newRange = previousRange.restrict( currentRange ); 145 if ( newRange.isSelectedVersionKnown( previous.getArtifact() ) ) 147 { 148 fireEvent( ResolutionListener.RESTRICT_RANGE, listeners, node, previous.getArtifact(), 149 newRange ); 150 } 151 previous.getArtifact().setVersionRange( newRange ); 152 node.getArtifact().setVersionRange( currentRange.restrict( previousRange ) ); 153 154 ResolutionNode[] resetNodes = {previous, node}; 158 for ( int j = 0; j < 2; j++ ) 159 { 160 Artifact resetArtifact = resetNodes[j].getArtifact(); 161 if ( resetArtifact.getVersion() == null && resetArtifact.getVersionRange() != null && 162 resetArtifact.getAvailableVersions() != null ) 163 { 164 165 resetArtifact.selectVersion( resetArtifact.getVersionRange().matchVersion( 166 resetArtifact.getAvailableVersions() ).toString() ); 167 fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, resetNodes[j] ); 168 } 169 } 170 } 171 172 175 ResolutionNode nearest; 178 ResolutionNode farthest; 179 if ( previous.getDepth() <= node.getDepth() ) 180 { 181 nearest = previous; 182 farthest = node; 183 } 184 else 185 { 186 nearest = node; 187 farthest = previous; 188 } 189 190 if ( checkScopeUpdate( farthest, nearest, listeners ) ) 191 { 192 nearest.disable(); 194 farthest.getArtifact().setVersion( nearest.getArtifact().getVersion() ); 195 } 196 else 197 { 198 farthest.disable(); 199 } 200 fireEvent( ResolutionListener.OMIT_FOR_NEARER, listeners, farthest, nearest.getArtifact() ); 201 } 202 } 203 } 204 else 205 { 206 previousNodes = new ArrayList (); 207 resolvedArtifacts.put( key, previousNodes ); 208 } 209 previousNodes.add( node ); 210 211 if ( node.isActive() ) 212 { 213 fireEvent( ResolutionListener.INCLUDE_ARTIFACT, listeners, node ); 214 } 215 216 if ( node.isActive() && !Artifact.SCOPE_SYSTEM.equals( node.getArtifact().getScope() ) ) 218 { 219 fireEvent( ResolutionListener.PROCESS_CHILDREN, listeners, node ); 220 221 for ( Iterator i = node.getChildrenIterator(); i.hasNext(); ) 222 { 223 ResolutionNode child = (ResolutionNode) i.next(); 224 if ( !child.isResolved() && ( !child.getArtifact().isOptional() || child.isChildOfRootNode() ) ) 226 { 227 Artifact artifact = child.getArtifact(); 228 try 229 { 230 if ( artifact.getVersion() == null ) 231 { 232 ArtifactVersion version; 235 if ( !artifact.isSelectedVersionKnown() ) 236 { 237 List versions = artifact.getAvailableVersions(); 238 if ( versions == null ) 239 { 240 versions = source.retrieveAvailableVersions( artifact, localRepository, 241 remoteRepositories ); 242 artifact.setAvailableVersions( versions ); 243 } 244 245 VersionRange versionRange = artifact.getVersionRange(); 246 247 version = versionRange.matchVersion( versions ); 248 249 if ( version == null ) 250 { 251 if ( versions.isEmpty() ) 252 { 253 throw new OverConstrainedVersionException( 254 "No versions are present in the repository for the artifact with a range " + 255 versionRange, artifact, remoteRepositories ); 256 } 257 else 258 { 259 throw new OverConstrainedVersionException( "Couldn't find a version in " + 260 versions + " to match range " + versionRange, artifact, 261 remoteRepositories ); 262 } 263 } 264 } 265 else 266 { 267 version = artifact.getSelectedVersion(); 268 } 269 270 artifact.selectVersion( version.toString() ); 271 fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, child ); 272 } 273 274 artifact.setDependencyTrail( node.getDependencyTrail() ); 275 ResolutionGroup rGroup = source.retrieve( artifact, localRepository, remoteRepositories ); 276 277 if ( rGroup == null ) 280 { 281 continue; 283 } 284 285 child.addDependencies( rGroup.getArtifacts(), rGroup.getResolutionRepositories(), filter ); 286 } 287 catch ( CyclicDependencyException e ) 288 { 289 291 fireEvent( ResolutionListener.OMIT_FOR_CYCLE, listeners, 292 new ResolutionNode( e.getArtifact(), remoteRepositories, child ) ); 293 } 294 catch ( ArtifactMetadataRetrievalException e ) 295 { 296 artifact.setDependencyTrail( node.getDependencyTrail() ); 297 throw new ArtifactResolutionException( 298 "Unable to get dependency information: " + e.getMessage(), artifact, remoteRepositories, 299 e ); 300 } 301 302 recurse( child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, 303 filter, listeners ); 304 } 305 } 306 307 fireEvent( ResolutionListener.FINISH_PROCESSING_CHILDREN, listeners, node ); 308 } 309 } 310 311 319 boolean checkScopeUpdate( ResolutionNode farthest, ResolutionNode nearest, List listeners ) 320 { 321 boolean updateScope = false; 322 Artifact farthestArtifact = farthest.getArtifact(); 323 Artifact nearestArtifact = nearest.getArtifact(); 324 325 if ( Artifact.SCOPE_RUNTIME.equals( farthestArtifact.getScope() ) && ( 326 Artifact.SCOPE_TEST.equals( nearestArtifact.getScope() ) || 327 Artifact.SCOPE_PROVIDED.equals( nearestArtifact.getScope() ) ) ) 328 { 329 updateScope = true; 330 } 331 332 if ( Artifact.SCOPE_COMPILE.equals( farthestArtifact.getScope() ) && 333 !Artifact.SCOPE_COMPILE.equals( nearestArtifact.getScope() ) ) 334 { 335 updateScope = true; 336 } 337 338 if ( nearest.getDepth() < 2 && updateScope ) 340 { 341 updateScope = false; 342 343 fireEvent( ResolutionListener.UPDATE_SCOPE_CURRENT_POM, listeners, nearest, farthestArtifact ); 344 } 345 346 if ( updateScope ) 347 { 348 fireEvent( ResolutionListener.UPDATE_SCOPE, listeners, nearest, farthestArtifact ); 349 350 nearestArtifact.setScope( farthestArtifact.getScope() ); 354 } 355 356 return updateScope; 357 } 358 359 private void fireEvent( int event, List listeners, ResolutionNode node ) 360 { 361 fireEvent( event, listeners, node, null ); 362 } 363 364 private void fireEvent( int event, List listeners, ResolutionNode node, Artifact replacement ) 365 { 366 fireEvent( event, listeners, node, replacement, null ); 367 } 368 369 private void fireEvent( int event, List listeners, ResolutionNode node, Artifact replacement, 370 VersionRange newRange ) 371 { 372 for ( Iterator i = listeners.iterator(); i.hasNext(); ) 373 { 374 ResolutionListener listener = (ResolutionListener) i.next(); 375 376 switch ( event ) 377 { 378 case ResolutionListener.TEST_ARTIFACT: 379 listener.testArtifact( node.getArtifact() ); 380 break; 381 case ResolutionListener.PROCESS_CHILDREN: 382 listener.startProcessChildren( node.getArtifact() ); 383 break; 384 case ResolutionListener.FINISH_PROCESSING_CHILDREN: 385 listener.endProcessChildren( node.getArtifact() ); 386 break; 387 case ResolutionListener.INCLUDE_ARTIFACT: 388 listener.includeArtifact( node.getArtifact() ); 389 break; 390 case ResolutionListener.OMIT_FOR_NEARER: 391 String version = node.getArtifact().getVersion(); 392 String replacementVersion = replacement.getVersion(); 393 if ( version != null ? !version.equals( replacementVersion ) : replacementVersion != null ) 394 { 395 listener.omitForNearer( node.getArtifact(), replacement ); 396 } 397 break; 398 case ResolutionListener.OMIT_FOR_CYCLE: 399 listener.omitForCycle( node.getArtifact() ); 400 break; 401 case ResolutionListener.UPDATE_SCOPE: 402 listener.updateScope( node.getArtifact(), replacement.getScope() ); 403 break; 404 case ResolutionListener.UPDATE_SCOPE_CURRENT_POM: 405 listener.updateScopeCurrentPom( node.getArtifact(), replacement.getScope() ); 406 break; 407 case ResolutionListener.MANAGE_ARTIFACT: 408 listener.manageArtifact( node.getArtifact(), replacement ); 409 break; 410 case ResolutionListener.SELECT_VERSION_FROM_RANGE: 411 listener.selectVersionFromRange( node.getArtifact() ); 412 break; 413 case ResolutionListener.RESTRICT_RANGE: 414 if ( node.getArtifact().getVersionRange().hasRestrictions() || 415 replacement.getVersionRange().hasRestrictions() ) 416 { 417 listener.restrictRange( node.getArtifact(), replacement, newRange ); 418 } 419 break; 420 default: 421 throw new IllegalStateException ( "Unknown event: " + event ); 422 } 423 } 424 } 425 426 } 427 | Popular Tags |