1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.IOException;
26 import java.nio.file.Files;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.concurrent.atomic.AtomicBoolean;
36
37 import org.eclipse.aether.ConfigurationProperties;
38 import org.eclipse.aether.RepositoryEvent;
39 import org.eclipse.aether.RepositoryEvent.EventType;
40 import org.eclipse.aether.RepositorySystemSession;
41 import org.eclipse.aether.RequestTrace;
42 import org.eclipse.aether.SyncContext;
43 import org.eclipse.aether.artifact.Artifact;
44 import org.eclipse.aether.impl.ArtifactResolver;
45 import org.eclipse.aether.impl.OfflineController;
46 import org.eclipse.aether.impl.RemoteRepositoryFilterManager;
47 import org.eclipse.aether.impl.RemoteRepositoryManager;
48 import org.eclipse.aether.impl.RepositoryConnectorProvider;
49 import org.eclipse.aether.impl.RepositoryEventDispatcher;
50 import org.eclipse.aether.impl.UpdateCheck;
51 import org.eclipse.aether.impl.UpdateCheckManager;
52 import org.eclipse.aether.impl.VersionResolver;
53 import org.eclipse.aether.repository.ArtifactRepository;
54 import org.eclipse.aether.repository.LocalArtifactRegistration;
55 import org.eclipse.aether.repository.LocalArtifactRequest;
56 import org.eclipse.aether.repository.LocalArtifactResult;
57 import org.eclipse.aether.repository.LocalRepository;
58 import org.eclipse.aether.repository.LocalRepositoryManager;
59 import org.eclipse.aether.repository.RemoteRepository;
60 import org.eclipse.aether.repository.RepositoryPolicy;
61 import org.eclipse.aether.repository.WorkspaceReader;
62 import org.eclipse.aether.resolution.ArtifactRequest;
63 import org.eclipse.aether.resolution.ArtifactResolutionException;
64 import org.eclipse.aether.resolution.ArtifactResult;
65 import org.eclipse.aether.resolution.ResolutionErrorPolicy;
66 import org.eclipse.aether.resolution.VersionRequest;
67 import org.eclipse.aether.resolution.VersionResolutionException;
68 import org.eclipse.aether.resolution.VersionResult;
69 import org.eclipse.aether.scope.SystemDependencyScope;
70 import org.eclipse.aether.spi.connector.ArtifactDownload;
71 import org.eclipse.aether.spi.connector.RepositoryConnector;
72 import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
73 import org.eclipse.aether.spi.io.PathProcessor;
74 import org.eclipse.aether.spi.resolution.ArtifactResolverPostProcessor;
75 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
76 import org.eclipse.aether.transfer.ArtifactFilteredOutException;
77 import org.eclipse.aether.transfer.ArtifactNotFoundException;
78 import org.eclipse.aether.transfer.ArtifactTransferException;
79 import org.eclipse.aether.transfer.NoRepositoryConnectorException;
80 import org.eclipse.aether.transfer.RepositoryOfflineException;
81 import org.eclipse.aether.util.ConfigUtils;
82 import org.slf4j.Logger;
83 import org.slf4j.LoggerFactory;
84
85 import static java.util.Objects.requireNonNull;
86
87
88
89
90 @Singleton
91 @Named
92 public class DefaultArtifactResolver implements ArtifactResolver {
93
94 public static final String CONFIG_PROPS_PREFIX = ConfigurationProperties.PREFIX_AETHER + "artifactResolver.";
95
96
97
98
99
100
101
102
103
104
105
106 public static final String CONFIG_PROP_SNAPSHOT_NORMALIZATION = CONFIG_PROPS_PREFIX + "snapshotNormalization";
107
108 public static final boolean DEFAULT_SNAPSHOT_NORMALIZATION = true;
109
110
111
112
113
114
115
116
117
118 public static final String CONFIG_PROP_SIMPLE_LRM_INTEROP = CONFIG_PROPS_PREFIX + "simpleLrmInterop";
119
120 public static final boolean DEFAULT_SIMPLE_LRM_INTEROP = false;
121
122 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultArtifactResolver.class);
123
124 private final PathProcessor pathProcessor;
125
126 private final RepositoryEventDispatcher repositoryEventDispatcher;
127
128 private final VersionResolver versionResolver;
129
130 private final UpdateCheckManager updateCheckManager;
131
132 private final RepositoryConnectorProvider repositoryConnectorProvider;
133
134 private final RemoteRepositoryManager remoteRepositoryManager;
135
136 private final SyncContextFactory syncContextFactory;
137
138 private final OfflineController offlineController;
139
140 private final Map<String, ArtifactResolverPostProcessor> artifactResolverPostProcessors;
141
142 private final RemoteRepositoryFilterManager remoteRepositoryFilterManager;
143
144 @SuppressWarnings("checkstyle:parameternumber")
145 @Inject
146 public DefaultArtifactResolver(
147 PathProcessor pathProcessor,
148 RepositoryEventDispatcher repositoryEventDispatcher,
149 VersionResolver versionResolver,
150 UpdateCheckManager updateCheckManager,
151 RepositoryConnectorProvider repositoryConnectorProvider,
152 RemoteRepositoryManager remoteRepositoryManager,
153 SyncContextFactory syncContextFactory,
154 OfflineController offlineController,
155 Map<String, ArtifactResolverPostProcessor> artifactResolverPostProcessors,
156 RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
157 this.pathProcessor = requireNonNull(pathProcessor, "path processor cannot be null");
158 this.repositoryEventDispatcher =
159 requireNonNull(repositoryEventDispatcher, "repository event dispatcher cannot be null");
160 this.versionResolver = requireNonNull(versionResolver, "version resolver cannot be null");
161 this.updateCheckManager = requireNonNull(updateCheckManager, "update check manager cannot be null");
162 this.repositoryConnectorProvider =
163 requireNonNull(repositoryConnectorProvider, "repository connector provider cannot be null");
164 this.remoteRepositoryManager =
165 requireNonNull(remoteRepositoryManager, "remote repository provider cannot be null");
166 this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
167 this.offlineController = requireNonNull(offlineController, "offline controller cannot be null");
168 this.artifactResolverPostProcessors =
169 requireNonNull(artifactResolverPostProcessors, "artifact resolver post-processors cannot be null");
170 this.remoteRepositoryFilterManager =
171 requireNonNull(remoteRepositoryFilterManager, "remote repository filter manager cannot be null");
172 }
173
174 @Override
175 public ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request)
176 throws ArtifactResolutionException {
177 requireNonNull(session, "session cannot be null");
178 requireNonNull(request, "request cannot be null");
179
180 return resolveArtifacts(session, Collections.singleton(request)).get(0);
181 }
182
183 @Override
184 public List<ArtifactResult> resolveArtifacts(
185 RepositorySystemSession session, Collection<? extends ArtifactRequest> requests)
186 throws ArtifactResolutionException {
187 requireNonNull(session, "session cannot be null");
188 requireNonNull(requests, "requests cannot be null");
189 try (SyncContext shared = syncContextFactory.newInstance(session, true);
190 SyncContext exclusive = syncContextFactory.newInstance(session, false)) {
191 Collection<Artifact> artifacts = new ArrayList<>(requests.size());
192 SystemDependencyScope systemDependencyScope = session.getSystemDependencyScope();
193 for (ArtifactRequest request : requests) {
194 if (systemDependencyScope != null
195 && systemDependencyScope.getSystemPath(request.getArtifact()) != null) {
196 continue;
197 }
198 artifacts.add(request.getArtifact());
199 }
200
201 return resolve(shared, exclusive, artifacts, session, requests);
202 }
203 }
204
205 @SuppressWarnings("checkstyle:methodlength")
206 private List<ArtifactResult> resolve(
207 SyncContext shared,
208 SyncContext exclusive,
209 Collection<Artifact> subjects,
210 RepositorySystemSession session,
211 Collection<? extends ArtifactRequest> requests)
212 throws ArtifactResolutionException {
213 SystemDependencyScope systemDependencyScope = session.getSystemDependencyScope();
214 SyncContext current = shared;
215 try {
216 while (true) {
217 current.acquire(subjects, null);
218
219 boolean failures = false;
220 final List<ArtifactResult> results = new ArrayList<>(requests.size());
221 final boolean simpleLrmInterop =
222 ConfigUtils.getBoolean(session, DEFAULT_SIMPLE_LRM_INTEROP, CONFIG_PROP_SIMPLE_LRM_INTEROP);
223 final LocalRepositoryManager lrm = session.getLocalRepositoryManager();
224 final WorkspaceReader workspace = session.getWorkspaceReader();
225 final List<ResolutionGroup> groups = new ArrayList<>();
226
227 final RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
228
229 for (ArtifactRequest request : requests) {
230 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
231
232 ArtifactResult result = new ArtifactResult(request);
233 results.add(result);
234
235 Artifact artifact = request.getArtifact();
236
237 if (current == shared) {
238 artifactResolving(session, trace, artifact);
239 }
240
241 String localPath =
242 systemDependencyScope != null ? systemDependencyScope.getSystemPath(artifact) : null;
243 if (localPath != null) {
244
245 Path path = Paths.get(localPath);
246 if (!Files.isRegularFile(path)) {
247 failures = true;
248 result.addException(
249 ArtifactResult.NO_REPOSITORY, new ArtifactNotFoundException(artifact, localPath));
250 } else {
251 artifact = artifact.setPath(path);
252 result.setArtifact(artifact);
253 artifactResolved(session, trace, artifact, null, result.getExceptions());
254 }
255 continue;
256 }
257
258 List<RemoteRepository> remoteRepositories = request.getRepositories();
259 List<RemoteRepository> filteredRemoteRepositories = new ArrayList<>(remoteRepositories);
260 if (filter != null) {
261 for (RemoteRepository repository : remoteRepositories) {
262 RemoteRepositoryFilter.Result filterResult = filter.acceptArtifact(repository, artifact);
263 if (!filterResult.isAccepted()) {
264 result.addException(
265 repository,
266 new ArtifactFilteredOutException(
267 artifact, repository, filterResult.reasoning()));
268 filteredRemoteRepositories.remove(repository);
269 }
270 }
271 }
272
273 VersionResult versionResult;
274 try {
275 VersionRequest versionRequest =
276 new VersionRequest(artifact, filteredRemoteRepositories, request.getRequestContext());
277 versionRequest.setTrace(trace);
278 versionResult = versionResolver.resolveVersion(session, versionRequest);
279 } catch (VersionResolutionException e) {
280 if (filteredRemoteRepositories.isEmpty()) {
281 result.addException(lrm.getRepository(), e);
282 } else {
283 filteredRemoteRepositories.forEach(r -> result.addException(r, e));
284 }
285 continue;
286 }
287
288 artifact = artifact.setVersion(versionResult.getVersion());
289
290 if (versionResult.getRepository() != null) {
291 if (versionResult.getRepository() instanceof RemoteRepository) {
292 filteredRemoteRepositories =
293 Collections.singletonList((RemoteRepository) versionResult.getRepository());
294 } else {
295 filteredRemoteRepositories = Collections.emptyList();
296 }
297 }
298
299 if (workspace != null) {
300 Path path = workspace.findArtifactPath(artifact);
301 if (path != null) {
302 artifact = artifact.setPath(path);
303 result.setArtifact(artifact);
304 result.setRepository(workspace.getRepository());
305 artifactResolved(session, trace, artifact, result.getRepository(), null);
306 continue;
307 }
308 }
309
310 LocalArtifactResult local = lrm.find(
311 session,
312 new LocalArtifactRequest(
313 artifact, filteredRemoteRepositories, request.getRequestContext()));
314 result.setLocalArtifactResult(local);
315 boolean found = (filter != null && local.isAvailable()) || isLocallyInstalled(local, versionResult);
316
317
318
319 if (found) {
320 if (local.getRepository() != null) {
321 result.setRepository(local.getRepository());
322 } else {
323 result.setRepository(lrm.getRepository());
324 }
325
326 try {
327 artifact = artifact.setPath(getPath(session, artifact, local.getPath()));
328 result.setArtifact(artifact);
329 artifactResolved(session, trace, artifact, result.getRepository(), null);
330 } catch (ArtifactTransferException e) {
331 result.addException(lrm.getRepository(), e);
332 }
333 if (filter == null && simpleLrmInterop && !local.isAvailable()) {
334
335
336
337
338
339
340 lrm.add(session, new LocalArtifactRegistration(artifact));
341 }
342
343 continue;
344 }
345
346 if (local.getPath() != null) {
347 LOGGER.info(
348 "Artifact {} is present in the local repository, but cached from a remote repository ID that is unavailable in current build context, verifying that is downloadable from {}",
349 artifact,
350 remoteRepositories);
351 }
352
353 LOGGER.debug("Resolving artifact {} from {}", artifact, remoteRepositories);
354 AtomicBoolean resolved = new AtomicBoolean(false);
355 Iterator<ResolutionGroup> groupIt = groups.iterator();
356 for (RemoteRepository repo : filteredRemoteRepositories) {
357 if (!repo.getPolicy(artifact.isSnapshot()).isEnabled()) {
358 continue;
359 }
360
361 try {
362 Utils.checkOffline(session, offlineController, repo);
363 } catch (RepositoryOfflineException e) {
364 Exception exception = new ArtifactNotFoundException(
365 artifact,
366 repo,
367 "Cannot access " + repo.getId() + " ("
368 + repo.getUrl() + ") in offline mode and the artifact " + artifact
369 + " has not been downloaded from it before.",
370 e);
371 result.addException(repo, exception);
372 continue;
373 }
374
375 ResolutionGroup group = null;
376 while (groupIt.hasNext()) {
377 ResolutionGroup t = groupIt.next();
378 if (t.matches(repo)) {
379 group = t;
380 break;
381 }
382 }
383 if (group == null) {
384 group = new ResolutionGroup(repo);
385 groups.add(group);
386 groupIt = Collections.emptyIterator();
387 }
388 group.items.add(new ResolutionItem(trace, artifact, resolved, result, local, repo));
389 }
390 }
391
392 if (!groups.isEmpty() && current == shared) {
393 current.close();
394 current = exclusive;
395 continue;
396 }
397
398 for (ResolutionGroup group : groups) {
399 performDownloads(session, group);
400 }
401
402 for (ArtifactResolverPostProcessor artifactResolverPostProcessor :
403 artifactResolverPostProcessors.values()) {
404 artifactResolverPostProcessor.postProcess(session, results);
405 }
406
407 for (ArtifactResult result : results) {
408 ArtifactRequest request = result.getRequest();
409
410 Artifact artifact = result.getArtifact();
411 if (artifact == null || artifact.getPath() == null) {
412 failures = true;
413 if (result.getExceptions().isEmpty()) {
414 Exception exception =
415 new ArtifactNotFoundException(request.getArtifact(), (RemoteRepository) null);
416 result.addException(result.getRepository(), exception);
417 }
418 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
419 artifactResolved(session, trace, request.getArtifact(), null, result.getExceptions());
420 }
421 }
422
423 if (failures) {
424 throw new ArtifactResolutionException(results);
425 }
426
427 return results;
428 }
429 } finally {
430 current.close();
431 }
432 }
433
434 private boolean isLocallyInstalled(LocalArtifactResult lar, VersionResult vr) {
435 if (lar.isAvailable()) {
436 return true;
437 }
438 if (lar.getPath() != null) {
439
440 if (vr.getRepository() instanceof LocalRepository) {
441
442 return true;
443 } else {
444 return vr.getRepository() == null
445 && lar.getRequest().getRepositories().isEmpty();
446 }
447 }
448 return false;
449 }
450
451 private Path getPath(RepositorySystemSession session, Artifact artifact, Path path)
452 throws ArtifactTransferException {
453 if (artifact.isSnapshot()
454 && !artifact.getVersion().equals(artifact.getBaseVersion())
455 && ConfigUtils.getBoolean(
456 session, DEFAULT_SNAPSHOT_NORMALIZATION, CONFIG_PROP_SNAPSHOT_NORMALIZATION)) {
457 String name = path.getFileName().toString().replace(artifact.getVersion(), artifact.getBaseVersion());
458 Path dst = path.getParent().resolve(name);
459
460 try {
461 long pathLastModified = pathProcessor.lastModified(path, 0L);
462 boolean copy = pathProcessor.size(dst, 0L) != pathProcessor.size(path, 0L)
463 || pathProcessor.lastModified(dst, 0L) != pathLastModified;
464 if (copy) {
465 pathProcessor.copyWithTimestamp(path, dst);
466 }
467 } catch (IOException e) {
468 throw new ArtifactTransferException(artifact, null, e);
469 }
470
471 path = dst;
472 }
473
474 return path;
475 }
476
477 private void performDownloads(RepositorySystemSession session, ResolutionGroup group) {
478 List<ArtifactDownload> downloads = gatherDownloads(session, group);
479 if (downloads.isEmpty()) {
480 return;
481 }
482
483 for (ArtifactDownload download : downloads) {
484 artifactDownloading(session, download.getTrace(), download.getArtifact(), group.repository);
485 }
486
487 try {
488 try (RepositoryConnector connector =
489 repositoryConnectorProvider.newRepositoryConnector(session, group.repository)) {
490 connector.get(downloads, null);
491 }
492 } catch (NoRepositoryConnectorException e) {
493 for (ArtifactDownload download : downloads) {
494 download.setException(new ArtifactTransferException(download.getArtifact(), group.repository, e));
495 }
496 }
497
498 evaluateDownloads(session, group);
499 }
500
501 private List<ArtifactDownload> gatherDownloads(RepositorySystemSession session, ResolutionGroup group) {
502 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
503 List<ArtifactDownload> downloads = new ArrayList<>();
504
505 for (ResolutionItem item : group.items) {
506 Artifact artifact = item.artifact;
507
508 if (item.resolved.get()) {
509
510 continue;
511 }
512
513 ArtifactDownload download = new ArtifactDownload();
514 download.setArtifact(artifact);
515 download.setRequestContext(item.request.getRequestContext());
516 download.setListener(SafeTransferListener.wrap(session));
517 download.setTrace(item.trace);
518 if (item.local.getPath() != null) {
519 download.setPath(item.local.getPath());
520 download.setExistenceCheck(true);
521 } else {
522 String path =
523 lrm.getPathForRemoteArtifact(artifact, group.repository, item.request.getRequestContext());
524 download.setPath(lrm.getRepository().getBasePath().resolve(path));
525 }
526
527 boolean snapshot = artifact.isSnapshot();
528 RepositoryPolicy policy = remoteRepositoryManager.getPolicy(session, group.repository, !snapshot, snapshot);
529
530 int errorPolicy = Utils.getPolicy(session, artifact, group.repository);
531 if ((errorPolicy & ResolutionErrorPolicy.CACHE_ALL) != 0) {
532 UpdateCheck<Artifact, ArtifactTransferException> check = new UpdateCheck<>();
533 check.setItem(artifact);
534 check.setPath(download.getPath());
535 check.setFileValid(false);
536 check.setRepository(group.repository);
537 check.setArtifactPolicy(policy.getArtifactUpdatePolicy());
538 check.setMetadataPolicy(policy.getMetadataUpdatePolicy());
539 item.updateCheck = check;
540 updateCheckManager.checkArtifact(session, check);
541 if (!check.isRequired()) {
542 item.result.addException(group.repository, check.getException());
543 continue;
544 }
545 }
546
547 download.setChecksumPolicy(policy.getChecksumPolicy());
548 download.setRepositories(item.repository.getMirroredRepositories());
549 downloads.add(download);
550 item.download = download;
551 }
552
553 return downloads;
554 }
555
556 private void evaluateDownloads(RepositorySystemSession session, ResolutionGroup group) {
557 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
558
559 for (ResolutionItem item : group.items) {
560 ArtifactDownload download = item.download;
561 if (download == null) {
562 continue;
563 }
564
565 Artifact artifact = download.getArtifact();
566 if (download.getException() == null) {
567 item.resolved.set(true);
568 item.result.setRepository(group.repository);
569 try {
570 artifact = artifact.setPath(getPath(session, artifact, download.getPath()));
571 item.result.setArtifact(artifact);
572
573 lrm.add(
574 session,
575 new LocalArtifactRegistration(artifact, group.repository, download.getSupportedContexts()));
576 } catch (ArtifactTransferException e) {
577 download.setException(e);
578 item.result.addException(group.repository, e);
579 }
580 } else {
581 item.result.addException(group.repository, download.getException());
582 }
583
584
585
586
587
588 if (item.updateCheck != null) {
589 item.updateCheck.setException(download.getException());
590 updateCheckManager.touchArtifact(session, item.updateCheck);
591 }
592
593 artifactDownloaded(session, download.getTrace(), artifact, group.repository, download.getException());
594 if (download.getException() == null) {
595 artifactResolved(session, download.getTrace(), artifact, group.repository, null);
596 }
597 }
598 }
599
600 private void artifactResolving(RepositorySystemSession session, RequestTrace trace, Artifact artifact) {
601 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVING);
602 event.setTrace(trace);
603 event.setArtifact(artifact);
604
605 repositoryEventDispatcher.dispatch(event.build());
606 }
607
608 private void artifactResolved(
609 RepositorySystemSession session,
610 RequestTrace trace,
611 Artifact artifact,
612 ArtifactRepository repository,
613 Collection<Exception> exceptions) {
614 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVED);
615 event.setTrace(trace);
616 event.setArtifact(artifact);
617 event.setRepository(repository);
618 event.setExceptions(exceptions != null ? new ArrayList<>(exceptions) : null);
619 if (artifact != null) {
620 event.setPath(artifact.getPath());
621 }
622
623 repositoryEventDispatcher.dispatch(event.build());
624 }
625
626 private void artifactDownloading(
627 RepositorySystemSession session, RequestTrace trace, Artifact artifact, RemoteRepository repository) {
628 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADING);
629 event.setTrace(trace);
630 event.setArtifact(artifact);
631 event.setRepository(repository);
632
633 repositoryEventDispatcher.dispatch(event.build());
634 }
635
636 private void artifactDownloaded(
637 RepositorySystemSession session,
638 RequestTrace trace,
639 Artifact artifact,
640 RemoteRepository repository,
641 Exception exception) {
642 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADED);
643 event.setTrace(trace);
644 event.setArtifact(artifact);
645 event.setRepository(repository);
646 event.setException(exception);
647 if (artifact != null) {
648 event.setPath(artifact.getPath());
649 }
650
651 repositoryEventDispatcher.dispatch(event.build());
652 }
653
654 static class ResolutionGroup {
655
656 final RemoteRepository repository;
657
658 final List<ResolutionItem> items = new ArrayList<>();
659
660 ResolutionGroup(RemoteRepository repository) {
661 this.repository = repository;
662 }
663
664 boolean matches(RemoteRepository repo) {
665 return repository.getUrl().equals(repo.getUrl())
666 && repository.getContentType().equals(repo.getContentType())
667 && repository.isRepositoryManager() == repo.isRepositoryManager();
668 }
669 }
670
671 static class ResolutionItem {
672
673 final RequestTrace trace;
674
675 final ArtifactRequest request;
676
677 final ArtifactResult result;
678
679 final LocalArtifactResult local;
680
681 final RemoteRepository repository;
682
683 final Artifact artifact;
684
685 final AtomicBoolean resolved;
686
687 ArtifactDownload download;
688
689 UpdateCheck<Artifact, ArtifactTransferException> updateCheck;
690
691 ResolutionItem(
692 RequestTrace trace,
693 Artifact artifact,
694 AtomicBoolean resolved,
695 ArtifactResult result,
696 LocalArtifactResult local,
697 RemoteRepository repository) {
698 this.trace = trace;
699 this.artifact = artifact;
700 this.resolved = resolved;
701 this.result = result;
702 this.request = result.getRequest();
703 this.local = local;
704 this.repository = repository;
705 }
706 }
707 }