001package org.eclipse.aether.internal.impl; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.File; 023import java.io.IOException; 024import java.util.ArrayList; 025import java.util.Collection; 026import java.util.Collections; 027import java.util.Iterator; 028import java.util.List; 029import static java.util.Objects.requireNonNull; 030import java.util.concurrent.atomic.AtomicBoolean; 031 032import javax.inject.Inject; 033import javax.inject.Named; 034 035import org.eclipse.aether.RepositoryEvent; 036import org.eclipse.aether.RepositoryEvent.EventType; 037import org.eclipse.aether.RepositorySystemSession; 038import org.eclipse.aether.RequestTrace; 039import org.eclipse.aether.SyncContext; 040import org.eclipse.aether.artifact.Artifact; 041import org.eclipse.aether.artifact.ArtifactProperties; 042import org.eclipse.aether.impl.ArtifactResolver; 043import org.eclipse.aether.impl.OfflineController; 044import org.eclipse.aether.impl.RemoteRepositoryManager; 045import org.eclipse.aether.impl.RepositoryConnectorProvider; 046import org.eclipse.aether.impl.RepositoryEventDispatcher; 047import org.eclipse.aether.impl.SyncContextFactory; 048import org.eclipse.aether.impl.UpdateCheck; 049import org.eclipse.aether.impl.UpdateCheckManager; 050import org.eclipse.aether.impl.VersionResolver; 051import org.eclipse.aether.repository.ArtifactRepository; 052import org.eclipse.aether.repository.LocalArtifactRegistration; 053import org.eclipse.aether.repository.LocalArtifactRequest; 054import org.eclipse.aether.repository.LocalArtifactResult; 055import org.eclipse.aether.repository.LocalRepository; 056import org.eclipse.aether.repository.LocalRepositoryManager; 057import org.eclipse.aether.repository.RemoteRepository; 058import org.eclipse.aether.repository.RepositoryPolicy; 059import org.eclipse.aether.repository.WorkspaceReader; 060import org.eclipse.aether.resolution.ArtifactRequest; 061import org.eclipse.aether.resolution.ArtifactResolutionException; 062import org.eclipse.aether.resolution.ArtifactResult; 063import org.eclipse.aether.resolution.ResolutionErrorPolicy; 064import org.eclipse.aether.resolution.VersionRequest; 065import org.eclipse.aether.resolution.VersionResolutionException; 066import org.eclipse.aether.resolution.VersionResult; 067import org.eclipse.aether.spi.connector.ArtifactDownload; 068import org.eclipse.aether.spi.connector.RepositoryConnector; 069import org.eclipse.aether.spi.io.FileProcessor; 070import org.eclipse.aether.spi.locator.Service; 071import org.eclipse.aether.spi.locator.ServiceLocator; 072import org.eclipse.aether.transfer.ArtifactNotFoundException; 073import org.eclipse.aether.transfer.ArtifactTransferException; 074import org.eclipse.aether.transfer.NoRepositoryConnectorException; 075import org.eclipse.aether.transfer.RepositoryOfflineException; 076import org.eclipse.aether.util.ConfigUtils; 077import org.slf4j.Logger; 078import org.slf4j.LoggerFactory; 079 080/** 081 */ 082@Named 083public class DefaultArtifactResolver 084 implements ArtifactResolver, Service 085{ 086 087 private static final String CONFIG_PROP_SNAPSHOT_NORMALIZATION = "aether.artifactResolver.snapshotNormalization"; 088 089 private static final Logger LOGGER = LoggerFactory.getLogger( DefaultArtifactResolver.class ); 090 091 private FileProcessor fileProcessor; 092 093 private RepositoryEventDispatcher repositoryEventDispatcher; 094 095 private VersionResolver versionResolver; 096 097 private UpdateCheckManager updateCheckManager; 098 099 private RepositoryConnectorProvider repositoryConnectorProvider; 100 101 private RemoteRepositoryManager remoteRepositoryManager; 102 103 private SyncContextFactory syncContextFactory; 104 105 private OfflineController offlineController; 106 107 public DefaultArtifactResolver() 108 { 109 // enables default constructor 110 } 111 112 @SuppressWarnings( "checkstyle:parameternumber" ) 113 @Inject 114 DefaultArtifactResolver( FileProcessor fileProcessor, RepositoryEventDispatcher repositoryEventDispatcher, 115 VersionResolver versionResolver, UpdateCheckManager updateCheckManager, 116 RepositoryConnectorProvider repositoryConnectorProvider, 117 RemoteRepositoryManager remoteRepositoryManager, SyncContextFactory syncContextFactory, 118 OfflineController offlineController ) 119 { 120 setFileProcessor( fileProcessor ); 121 setRepositoryEventDispatcher( repositoryEventDispatcher ); 122 setVersionResolver( versionResolver ); 123 setUpdateCheckManager( updateCheckManager ); 124 setRepositoryConnectorProvider( repositoryConnectorProvider ); 125 setRemoteRepositoryManager( remoteRepositoryManager ); 126 setSyncContextFactory( syncContextFactory ); 127 setOfflineController( offlineController ); 128 } 129 130 public void initService( ServiceLocator locator ) 131 { 132 setFileProcessor( locator.getService( FileProcessor.class ) ); 133 setRepositoryEventDispatcher( locator.getService( RepositoryEventDispatcher.class ) ); 134 setVersionResolver( locator.getService( VersionResolver.class ) ); 135 setUpdateCheckManager( locator.getService( UpdateCheckManager.class ) ); 136 setRepositoryConnectorProvider( locator.getService( RepositoryConnectorProvider.class ) ); 137 setRemoteRepositoryManager( locator.getService( RemoteRepositoryManager.class ) ); 138 setSyncContextFactory( locator.getService( SyncContextFactory.class ) ); 139 setOfflineController( locator.getService( OfflineController.class ) ); 140 } 141 142 /** 143 * @deprecated not used any more since MRESOLVER-36 move to slf4j, added back in MRESOLVER-64 for compatibility 144 */ 145 @Deprecated 146 public DefaultArtifactResolver setLoggerFactory( org.eclipse.aether.spi.log.LoggerFactory loggerFactory ) 147 { 148 // this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() ); 149 return this; 150 } 151 152 public DefaultArtifactResolver setFileProcessor( FileProcessor fileProcessor ) 153 { 154 this.fileProcessor = requireNonNull( fileProcessor, "file processor cannot be null" ); 155 return this; 156 } 157 158 public DefaultArtifactResolver setRepositoryEventDispatcher( RepositoryEventDispatcher repositoryEventDispatcher ) 159 { 160 this.repositoryEventDispatcher = requireNonNull( repositoryEventDispatcher, 161 "repository event dispatcher cannot be null" ); 162 return this; 163 } 164 165 public DefaultArtifactResolver setVersionResolver( VersionResolver versionResolver ) 166 { 167 this.versionResolver = requireNonNull( versionResolver, "version resolver cannot be null" ); 168 return this; 169 } 170 171 public DefaultArtifactResolver setUpdateCheckManager( UpdateCheckManager updateCheckManager ) 172 { 173 this.updateCheckManager = requireNonNull( updateCheckManager, "update check manager cannot be null" ); 174 return this; 175 } 176 177 public DefaultArtifactResolver setRepositoryConnectorProvider( 178 RepositoryConnectorProvider repositoryConnectorProvider ) 179 { 180 this.repositoryConnectorProvider = requireNonNull( repositoryConnectorProvider, 181 "repository connector provider cannot be null" ); 182 return this; 183 } 184 185 public DefaultArtifactResolver setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) 186 { 187 this.remoteRepositoryManager = requireNonNull( remoteRepositoryManager, 188 "remote repository provider cannot be null" ); 189 return this; 190 } 191 192 public DefaultArtifactResolver setSyncContextFactory( SyncContextFactory syncContextFactory ) 193 { 194 this.syncContextFactory = requireNonNull( syncContextFactory, "sync context factory cannot be null" ); 195 return this; 196 } 197 198 public DefaultArtifactResolver setOfflineController( OfflineController offlineController ) 199 { 200 this.offlineController = requireNonNull( offlineController, "offline controller cannot be null" ); 201 return this; 202 } 203 204 public ArtifactResult resolveArtifact( RepositorySystemSession session, ArtifactRequest request ) 205 throws ArtifactResolutionException 206 { 207 return resolveArtifacts( session, Collections.singleton( request ) ).get( 0 ); 208 } 209 210 public List<ArtifactResult> resolveArtifacts( RepositorySystemSession session, 211 Collection<? extends ArtifactRequest> requests ) 212 throws ArtifactResolutionException 213 { 214 215 try ( SyncContext syncContext = syncContextFactory.newInstance( session, false ) ) 216 { 217 Collection<Artifact> artifacts = new ArrayList<>( requests.size() ); 218 for ( ArtifactRequest request : requests ) 219 { 220 if ( request.getArtifact().getProperty( ArtifactProperties.LOCAL_PATH, null ) != null ) 221 { 222 continue; 223 } 224 artifacts.add( request.getArtifact() ); 225 } 226 227 syncContext.acquire( artifacts, null ); 228 229 return resolve( session, requests ); 230 } 231 } 232 233 @SuppressWarnings( "checkstyle:methodlength" ) 234 private List<ArtifactResult> resolve( RepositorySystemSession session, 235 Collection<? extends ArtifactRequest> requests ) 236 throws ArtifactResolutionException 237 { 238 List<ArtifactResult> results = new ArrayList<>( requests.size() ); 239 boolean failures = false; 240 241 LocalRepositoryManager lrm = session.getLocalRepositoryManager(); 242 WorkspaceReader workspace = session.getWorkspaceReader(); 243 244 List<ResolutionGroup> groups = new ArrayList<>(); 245 246 for ( ArtifactRequest request : requests ) 247 { 248 RequestTrace trace = RequestTrace.newChild( request.getTrace(), request ); 249 250 ArtifactResult result = new ArtifactResult( request ); 251 results.add( result ); 252 253 Artifact artifact = request.getArtifact(); 254 List<RemoteRepository> repos = request.getRepositories(); 255 256 artifactResolving( session, trace, artifact ); 257 258 String localPath = artifact.getProperty( ArtifactProperties.LOCAL_PATH, null ); 259 if ( localPath != null ) 260 { 261 // unhosted artifact, just validate file 262 File file = new File( localPath ); 263 if ( !file.isFile() ) 264 { 265 failures = true; 266 result.addException( new ArtifactNotFoundException( artifact, null ) ); 267 } 268 else 269 { 270 artifact = artifact.setFile( file ); 271 result.setArtifact( artifact ); 272 artifactResolved( session, trace, artifact, null, result.getExceptions() ); 273 } 274 continue; 275 } 276 277 VersionResult versionResult; 278 try 279 { 280 VersionRequest versionRequest = new VersionRequest( artifact, repos, request.getRequestContext() ); 281 versionRequest.setTrace( trace ); 282 versionResult = versionResolver.resolveVersion( session, versionRequest ); 283 } 284 catch ( VersionResolutionException e ) 285 { 286 result.addException( e ); 287 continue; 288 } 289 290 artifact = artifact.setVersion( versionResult.getVersion() ); 291 292 if ( versionResult.getRepository() != null ) 293 { 294 if ( versionResult.getRepository() instanceof RemoteRepository ) 295 { 296 repos = Collections.singletonList( (RemoteRepository) versionResult.getRepository() ); 297 } 298 else 299 { 300 repos = Collections.emptyList(); 301 } 302 } 303 304 if ( workspace != null ) 305 { 306 File file = workspace.findArtifact( artifact ); 307 if ( file != null ) 308 { 309 artifact = artifact.setFile( file ); 310 result.setArtifact( artifact ); 311 result.setRepository( workspace.getRepository() ); 312 artifactResolved( session, trace, artifact, result.getRepository(), null ); 313 continue; 314 } 315 } 316 317 LocalArtifactResult local = 318 lrm.find( session, new LocalArtifactRequest( artifact, repos, request.getRequestContext() ) ); 319 if ( isLocallyInstalled( local, versionResult ) ) 320 { 321 if ( local.getRepository() != null ) 322 { 323 result.setRepository( local.getRepository() ); 324 } 325 else 326 { 327 result.setRepository( lrm.getRepository() ); 328 } 329 try 330 { 331 artifact = artifact.setFile( getFile( session, artifact, local.getFile() ) ); 332 result.setArtifact( artifact ); 333 artifactResolved( session, trace, artifact, result.getRepository(), null ); 334 } 335 catch ( ArtifactTransferException e ) 336 { 337 result.addException( e ); 338 } 339 if ( !local.isAvailable() ) 340 { 341 /* 342 * NOTE: Interop with simple local repository: An artifact installed by a simple local repo manager 343 * will not show up in the repository tracking file of the enhanced local repository. If however the 344 * maven-metadata-local.xml tells us the artifact was installed locally, we sync the repository 345 * tracking file. 346 */ 347 lrm.add( session, new LocalArtifactRegistration( artifact ) ); 348 } 349 continue; 350 } 351 else if ( local.getFile() != null ) 352 { 353 LOGGER.debug( "Verifying availability of {} from {}", local.getFile(), repos ); 354 } 355 356 AtomicBoolean resolved = new AtomicBoolean( false ); 357 Iterator<ResolutionGroup> groupIt = groups.iterator(); 358 for ( RemoteRepository repo : repos ) 359 { 360 if ( !repo.getPolicy( artifact.isSnapshot() ).isEnabled() ) 361 { 362 continue; 363 } 364 365 try 366 { 367 Utils.checkOffline( session, offlineController, repo ); 368 } 369 catch ( RepositoryOfflineException e ) 370 { 371 Exception exception = 372 new ArtifactNotFoundException( artifact, repo, "Cannot access " + repo.getId() + " (" 373 + repo.getUrl() + ") in offline mode and the artifact " + artifact 374 + " has not been downloaded from it before.", e ); 375 result.addException( exception ); 376 continue; 377 } 378 379 ResolutionGroup group = null; 380 while ( groupIt.hasNext() ) 381 { 382 ResolutionGroup t = groupIt.next(); 383 if ( t.matches( repo ) ) 384 { 385 group = t; 386 break; 387 } 388 } 389 if ( group == null ) 390 { 391 group = new ResolutionGroup( repo ); 392 groups.add( group ); 393 groupIt = Collections.<ResolutionGroup>emptyList().iterator(); 394 } 395 group.items.add( new ResolutionItem( trace, artifact, resolved, result, local, repo ) ); 396 } 397 } 398 399 for ( ResolutionGroup group : groups ) 400 { 401 performDownloads( session, group ); 402 } 403 404 for ( ArtifactResult result : results ) 405 { 406 ArtifactRequest request = result.getRequest(); 407 408 Artifact artifact = result.getArtifact(); 409 if ( artifact == null || artifact.getFile() == null ) 410 { 411 failures = true; 412 if ( result.getExceptions().isEmpty() ) 413 { 414 Exception exception = new ArtifactNotFoundException( request.getArtifact(), null ); 415 result.addException( exception ); 416 } 417 RequestTrace trace = RequestTrace.newChild( request.getTrace(), request ); 418 artifactResolved( session, trace, request.getArtifact(), null, result.getExceptions() ); 419 } 420 } 421 422 if ( failures ) 423 { 424 throw new ArtifactResolutionException( results ); 425 } 426 427 return results; 428 } 429 430 private boolean isLocallyInstalled( LocalArtifactResult lar, VersionResult vr ) 431 { 432 if ( lar.isAvailable() ) 433 { 434 return true; 435 } 436 if ( lar.getFile() != null ) 437 { 438 if ( vr.getRepository() instanceof LocalRepository ) 439 { 440 // resolution of (snapshot) version found locally installed artifact 441 return true; 442 } 443 else if ( vr.getRepository() == null && lar.getRequest().getRepositories().isEmpty() ) 444 { 445 // resolution of version range found locally installed artifact 446 return true; 447 } 448 } 449 return false; 450 } 451 452 private File getFile( RepositorySystemSession session, Artifact artifact, File file ) 453 throws ArtifactTransferException 454 { 455 if ( artifact.isSnapshot() && !artifact.getVersion().equals( artifact.getBaseVersion() ) 456 && ConfigUtils.getBoolean( session, true, CONFIG_PROP_SNAPSHOT_NORMALIZATION ) ) 457 { 458 String name = file.getName().replace( artifact.getVersion(), artifact.getBaseVersion() ); 459 File dst = new File( file.getParent(), name ); 460 461 boolean copy = dst.length() != file.length() || dst.lastModified() != file.lastModified(); 462 if ( copy ) 463 { 464 try 465 { 466 fileProcessor.copy( file, dst ); 467 dst.setLastModified( file.lastModified() ); 468 } 469 catch ( IOException e ) 470 { 471 throw new ArtifactTransferException( artifact, null, e ); 472 } 473 } 474 475 file = dst; 476 } 477 478 return file; 479 } 480 481 private void performDownloads( RepositorySystemSession session, ResolutionGroup group ) 482 { 483 List<ArtifactDownload> downloads = gatherDownloads( session, group ); 484 if ( downloads.isEmpty() ) 485 { 486 return; 487 } 488 489 for ( ArtifactDownload download : downloads ) 490 { 491 artifactDownloading( session, download.getTrace(), download.getArtifact(), group.repository ); 492 } 493 494 try 495 { 496 RemoteRepository repo = group.repository; 497 if ( repo.isBlocked() ) 498 { 499 if ( repo.getMirroredRepositories().isEmpty() ) 500 { 501 throw new NoRepositoryConnectorException( repo, "Blocked repository: " + repo ); 502 } 503 else 504 { 505 throw new NoRepositoryConnectorException( repo, "Blocked mirror for repositories: " 506 + repo.getMirroredRepositories() ); 507 } 508 } 509 510 try ( RepositoryConnector connector = 511 repositoryConnectorProvider.newRepositoryConnector( session, group.repository ) ) 512 { 513 connector.get( downloads, null ); 514 } 515 } 516 catch ( NoRepositoryConnectorException e ) 517 { 518 for ( ArtifactDownload download : downloads ) 519 { 520 download.setException( new ArtifactTransferException( download.getArtifact(), group.repository, e ) ); 521 } 522 } 523 524 evaluateDownloads( session, group ); 525 } 526 527 private List<ArtifactDownload> gatherDownloads( RepositorySystemSession session, ResolutionGroup group ) 528 { 529 LocalRepositoryManager lrm = session.getLocalRepositoryManager(); 530 List<ArtifactDownload> downloads = new ArrayList<>(); 531 532 for ( ResolutionItem item : group.items ) 533 { 534 Artifact artifact = item.artifact; 535 536 if ( item.resolved.get() ) 537 { 538 // resolved in previous resolution group 539 continue; 540 } 541 542 ArtifactDownload download = new ArtifactDownload(); 543 download.setArtifact( artifact ); 544 download.setRequestContext( item.request.getRequestContext() ); 545 download.setListener( SafeTransferListener.wrap( session ) ); 546 download.setTrace( item.trace ); 547 if ( item.local.getFile() != null ) 548 { 549 download.setFile( item.local.getFile() ); 550 download.setExistenceCheck( true ); 551 } 552 else 553 { 554 String path = 555 lrm.getPathForRemoteArtifact( artifact, group.repository, item.request.getRequestContext() ); 556 download.setFile( new File( lrm.getRepository().getBasedir(), path ) ); 557 } 558 559 boolean snapshot = artifact.isSnapshot(); 560 RepositoryPolicy policy = 561 remoteRepositoryManager.getPolicy( session, group.repository, !snapshot, snapshot ); 562 563 int errorPolicy = Utils.getPolicy( session, artifact, group.repository ); 564 if ( ( errorPolicy & ResolutionErrorPolicy.CACHE_ALL ) != 0 ) 565 { 566 UpdateCheck<Artifact, ArtifactTransferException> check = new UpdateCheck<>(); 567 check.setItem( artifact ); 568 check.setFile( download.getFile() ); 569 check.setFileValid( false ); 570 check.setRepository( group.repository ); 571 check.setPolicy( policy.getUpdatePolicy() ); 572 item.updateCheck = check; 573 updateCheckManager.checkArtifact( session, check ); 574 if ( !check.isRequired() ) 575 { 576 item.result.addException( check.getException() ); 577 continue; 578 } 579 } 580 581 download.setChecksumPolicy( policy.getChecksumPolicy() ); 582 download.setRepositories( item.repository.getMirroredRepositories() ); 583 downloads.add( download ); 584 item.download = download; 585 } 586 587 return downloads; 588 } 589 590 private void evaluateDownloads( RepositorySystemSession session, ResolutionGroup group ) 591 { 592 LocalRepositoryManager lrm = session.getLocalRepositoryManager(); 593 594 for ( ResolutionItem item : group.items ) 595 { 596 ArtifactDownload download = item.download; 597 if ( download == null ) 598 { 599 continue; 600 } 601 602 Artifact artifact = download.getArtifact(); 603 if ( download.getException() == null ) 604 { 605 item.resolved.set( true ); 606 item.result.setRepository( group.repository ); 607 try 608 { 609 artifact = artifact.setFile( getFile( session, artifact, download.getFile() ) ); 610 item.result.setArtifact( artifact ); 611 612 lrm.add( session, new LocalArtifactRegistration( 613 artifact, group.repository, download.getSupportedContexts() ) ); 614 } 615 catch ( ArtifactTransferException e ) 616 { 617 download.setException( e ); 618 item.result.addException( e ); 619 } 620 } 621 else 622 { 623 item.result.addException( download.getException() ); 624 } 625 626 /* 627 * NOTE: Touch after registration with local repo to ensure concurrent resolution is not rejected with 628 * "already updated" via session data when actual update to local repo is still pending. 629 */ 630 if ( item.updateCheck != null ) 631 { 632 item.updateCheck.setException( download.getException() ); 633 updateCheckManager.touchArtifact( session, item.updateCheck ); 634 } 635 636 artifactDownloaded( session, download.getTrace(), artifact, group.repository, download.getException() ); 637 if ( download.getException() == null ) 638 { 639 artifactResolved( session, download.getTrace(), artifact, group.repository, null ); 640 } 641 } 642 } 643 644 private void artifactResolving( RepositorySystemSession session, RequestTrace trace, Artifact artifact ) 645 { 646 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_RESOLVING ); 647 event.setTrace( trace ); 648 event.setArtifact( artifact ); 649 650 repositoryEventDispatcher.dispatch( event.build() ); 651 } 652 653 private void artifactResolved( RepositorySystemSession session, RequestTrace trace, Artifact artifact, 654 ArtifactRepository repository, List<Exception> exceptions ) 655 { 656 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_RESOLVED ); 657 event.setTrace( trace ); 658 event.setArtifact( artifact ); 659 event.setRepository( repository ); 660 event.setExceptions( exceptions ); 661 if ( artifact != null ) 662 { 663 event.setFile( artifact.getFile() ); 664 } 665 666 repositoryEventDispatcher.dispatch( event.build() ); 667 } 668 669 private void artifactDownloading( RepositorySystemSession session, RequestTrace trace, Artifact artifact, 670 RemoteRepository repository ) 671 { 672 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DOWNLOADING ); 673 event.setTrace( trace ); 674 event.setArtifact( artifact ); 675 event.setRepository( repository ); 676 677 repositoryEventDispatcher.dispatch( event.build() ); 678 } 679 680 private void artifactDownloaded( RepositorySystemSession session, RequestTrace trace, Artifact artifact, 681 RemoteRepository repository, Exception exception ) 682 { 683 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DOWNLOADED ); 684 event.setTrace( trace ); 685 event.setArtifact( artifact ); 686 event.setRepository( repository ); 687 event.setException( exception ); 688 if ( artifact != null ) 689 { 690 event.setFile( artifact.getFile() ); 691 } 692 693 repositoryEventDispatcher.dispatch( event.build() ); 694 } 695 696 static class ResolutionGroup 697 { 698 699 final RemoteRepository repository; 700 701 final List<ResolutionItem> items = new ArrayList<>(); 702 703 ResolutionGroup( RemoteRepository repository ) 704 { 705 this.repository = repository; 706 } 707 708 boolean matches( RemoteRepository repo ) 709 { 710 return repository.getUrl().equals( repo.getUrl() ) 711 && repository.getContentType().equals( repo.getContentType() ) 712 && repository.isRepositoryManager() == repo.isRepositoryManager(); 713 } 714 715 } 716 717 static class ResolutionItem 718 { 719 720 final RequestTrace trace; 721 722 final ArtifactRequest request; 723 724 final ArtifactResult result; 725 726 final LocalArtifactResult local; 727 728 final RemoteRepository repository; 729 730 final Artifact artifact; 731 732 final AtomicBoolean resolved; 733 734 ArtifactDownload download; 735 736 UpdateCheck<Artifact, ArtifactTransferException> updateCheck; 737 738 ResolutionItem( RequestTrace trace, Artifact artifact, AtomicBoolean resolved, ArtifactResult result, 739 LocalArtifactResult local, RemoteRepository repository ) 740 { 741 this.trace = trace; 742 this.artifact = artifact; 743 this.resolved = resolved; 744 this.result = result; 745 this.request = result.getRequest(); 746 this.local = local; 747 this.repository = repository; 748 } 749 750 } 751 752}