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 try ( RepositoryConnector connector = 497 repositoryConnectorProvider.newRepositoryConnector( session, group.repository ) ) 498 { 499 connector.get( downloads, null ); 500 } 501 } 502 catch ( NoRepositoryConnectorException e ) 503 { 504 for ( ArtifactDownload download : downloads ) 505 { 506 download.setException( new ArtifactTransferException( download.getArtifact(), group.repository, e ) ); 507 } 508 } 509 510 evaluateDownloads( session, group ); 511 } 512 513 private List<ArtifactDownload> gatherDownloads( RepositorySystemSession session, ResolutionGroup group ) 514 { 515 LocalRepositoryManager lrm = session.getLocalRepositoryManager(); 516 List<ArtifactDownload> downloads = new ArrayList<>(); 517 518 for ( ResolutionItem item : group.items ) 519 { 520 Artifact artifact = item.artifact; 521 522 if ( item.resolved.get() ) 523 { 524 // resolved in previous resolution group 525 continue; 526 } 527 528 ArtifactDownload download = new ArtifactDownload(); 529 download.setArtifact( artifact ); 530 download.setRequestContext( item.request.getRequestContext() ); 531 download.setListener( SafeTransferListener.wrap( session ) ); 532 download.setTrace( item.trace ); 533 if ( item.local.getFile() != null ) 534 { 535 download.setFile( item.local.getFile() ); 536 download.setExistenceCheck( true ); 537 } 538 else 539 { 540 String path = 541 lrm.getPathForRemoteArtifact( artifact, group.repository, item.request.getRequestContext() ); 542 download.setFile( new File( lrm.getRepository().getBasedir(), path ) ); 543 } 544 545 boolean snapshot = artifact.isSnapshot(); 546 RepositoryPolicy policy = 547 remoteRepositoryManager.getPolicy( session, group.repository, !snapshot, snapshot ); 548 549 int errorPolicy = Utils.getPolicy( session, artifact, group.repository ); 550 if ( ( errorPolicy & ResolutionErrorPolicy.CACHE_ALL ) != 0 ) 551 { 552 UpdateCheck<Artifact, ArtifactTransferException> check = new UpdateCheck<>(); 553 check.setItem( artifact ); 554 check.setFile( download.getFile() ); 555 check.setFileValid( false ); 556 check.setRepository( group.repository ); 557 check.setPolicy( policy.getUpdatePolicy() ); 558 item.updateCheck = check; 559 updateCheckManager.checkArtifact( session, check ); 560 if ( !check.isRequired() ) 561 { 562 item.result.addException( check.getException() ); 563 continue; 564 } 565 } 566 567 download.setChecksumPolicy( policy.getChecksumPolicy() ); 568 download.setRepositories( item.repository.getMirroredRepositories() ); 569 downloads.add( download ); 570 item.download = download; 571 } 572 573 return downloads; 574 } 575 576 private void evaluateDownloads( RepositorySystemSession session, ResolutionGroup group ) 577 { 578 LocalRepositoryManager lrm = session.getLocalRepositoryManager(); 579 580 for ( ResolutionItem item : group.items ) 581 { 582 ArtifactDownload download = item.download; 583 if ( download == null ) 584 { 585 continue; 586 } 587 588 Artifact artifact = download.getArtifact(); 589 if ( download.getException() == null ) 590 { 591 item.resolved.set( true ); 592 item.result.setRepository( group.repository ); 593 try 594 { 595 artifact = artifact.setFile( getFile( session, artifact, download.getFile() ) ); 596 item.result.setArtifact( artifact ); 597 598 lrm.add( session, new LocalArtifactRegistration( 599 artifact, group.repository, download.getSupportedContexts() ) ); 600 } 601 catch ( ArtifactTransferException e ) 602 { 603 download.setException( e ); 604 item.result.addException( e ); 605 } 606 } 607 else 608 { 609 item.result.addException( download.getException() ); 610 } 611 612 /* 613 * NOTE: Touch after registration with local repo to ensure concurrent resolution is not rejected with 614 * "already updated" via session data when actual update to local repo is still pending. 615 */ 616 if ( item.updateCheck != null ) 617 { 618 item.updateCheck.setException( download.getException() ); 619 updateCheckManager.touchArtifact( session, item.updateCheck ); 620 } 621 622 artifactDownloaded( session, download.getTrace(), artifact, group.repository, download.getException() ); 623 if ( download.getException() == null ) 624 { 625 artifactResolved( session, download.getTrace(), artifact, group.repository, null ); 626 } 627 } 628 } 629 630 private void artifactResolving( RepositorySystemSession session, RequestTrace trace, Artifact artifact ) 631 { 632 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_RESOLVING ); 633 event.setTrace( trace ); 634 event.setArtifact( artifact ); 635 636 repositoryEventDispatcher.dispatch( event.build() ); 637 } 638 639 private void artifactResolved( RepositorySystemSession session, RequestTrace trace, Artifact artifact, 640 ArtifactRepository repository, List<Exception> exceptions ) 641 { 642 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_RESOLVED ); 643 event.setTrace( trace ); 644 event.setArtifact( artifact ); 645 event.setRepository( repository ); 646 event.setExceptions( exceptions ); 647 if ( artifact != null ) 648 { 649 event.setFile( artifact.getFile() ); 650 } 651 652 repositoryEventDispatcher.dispatch( event.build() ); 653 } 654 655 private void artifactDownloading( RepositorySystemSession session, RequestTrace trace, Artifact artifact, 656 RemoteRepository repository ) 657 { 658 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DOWNLOADING ); 659 event.setTrace( trace ); 660 event.setArtifact( artifact ); 661 event.setRepository( repository ); 662 663 repositoryEventDispatcher.dispatch( event.build() ); 664 } 665 666 private void artifactDownloaded( RepositorySystemSession session, RequestTrace trace, Artifact artifact, 667 RemoteRepository repository, Exception exception ) 668 { 669 RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DOWNLOADED ); 670 event.setTrace( trace ); 671 event.setArtifact( artifact ); 672 event.setRepository( repository ); 673 event.setException( exception ); 674 if ( artifact != null ) 675 { 676 event.setFile( artifact.getFile() ); 677 } 678 679 repositoryEventDispatcher.dispatch( event.build() ); 680 } 681 682 static class ResolutionGroup 683 { 684 685 final RemoteRepository repository; 686 687 final List<ResolutionItem> items = new ArrayList<>(); 688 689 ResolutionGroup( RemoteRepository repository ) 690 { 691 this.repository = repository; 692 } 693 694 boolean matches( RemoteRepository repo ) 695 { 696 return repository.getUrl().equals( repo.getUrl() ) 697 && repository.getContentType().equals( repo.getContentType() ) 698 && repository.isRepositoryManager() == repo.isRepositoryManager(); 699 } 700 701 } 702 703 static class ResolutionItem 704 { 705 706 final RequestTrace trace; 707 708 final ArtifactRequest request; 709 710 final ArtifactResult result; 711 712 final LocalArtifactResult local; 713 714 final RemoteRepository repository; 715 716 final Artifact artifact; 717 718 final AtomicBoolean resolved; 719 720 ArtifactDownload download; 721 722 UpdateCheck<Artifact, ArtifactTransferException> updateCheck; 723 724 ResolutionItem( RequestTrace trace, Artifact artifact, AtomicBoolean resolved, ArtifactResult result, 725 LocalArtifactResult local, RemoteRepository repository ) 726 { 727 this.trace = trace; 728 this.artifact = artifact; 729 this.resolved = resolved; 730 this.result = result; 731 this.request = result.getRequest(); 732 this.local = local; 733 this.repository = repository; 734 } 735 736 } 737 738}