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