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