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())
316 || (filter == null && isLocallyInstalled(local, versionResult));
317
318
319
320 if (found) {
321 if (local.getRepository() != null) {
322 result.setRepository(local.getRepository());
323 } else {
324 result.setRepository(lrm.getRepository());
325 }
326
327 try {
328 artifact = artifact.setPath(getPath(session, artifact, local.getPath()));
329 result.setArtifact(artifact);
330 artifactResolved(session, trace, artifact, result.getRepository(), null);
331 } catch (ArtifactTransferException e) {
332 result.addException(lrm.getRepository(), e);
333 }
334 if (filter == null && simpleLrmInterop && !local.isAvailable()) {
335
336
337
338
339
340
341 lrm.add(session, new LocalArtifactRegistration(artifact));
342 }
343
344 continue;
345 }
346
347 if (local.getPath() != null) {
348 LOGGER.info(
349 "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 {}",
350 artifact,
351 remoteRepositories);
352 }
353
354 LOGGER.debug("Resolving artifact {} from {}", artifact, remoteRepositories);
355 AtomicBoolean resolved = new AtomicBoolean(false);
356 Iterator<ResolutionGroup> groupIt = groups.iterator();
357 for (RemoteRepository repo : filteredRemoteRepositories) {
358 if (!repo.getPolicy(artifact.isSnapshot()).isEnabled()) {
359 continue;
360 }
361
362 try {
363 Utils.checkOffline(session, offlineController, repo);
364 } catch (RepositoryOfflineException e) {
365 Exception exception = new ArtifactNotFoundException(
366 artifact,
367 repo,
368 "Cannot access " + repo.getId() + " ("
369 + repo.getUrl() + ") in offline mode and the artifact " + artifact
370 + " has not been downloaded from it before.",
371 e);
372 result.addException(repo, exception);
373 continue;
374 }
375
376 ResolutionGroup group = null;
377 while (groupIt.hasNext()) {
378 ResolutionGroup t = groupIt.next();
379 if (t.matches(repo)) {
380 group = t;
381 break;
382 }
383 }
384 if (group == null) {
385 group = new ResolutionGroup(repo);
386 groups.add(group);
387 groupIt = Collections.emptyIterator();
388 }
389 group.items.add(new ResolutionItem(trace, artifact, resolved, result, local, repo));
390 }
391 }
392
393 if (!groups.isEmpty() && current == shared) {
394 current.close();
395 current = exclusive;
396 continue;
397 }
398
399 for (ResolutionGroup group : groups) {
400 performDownloads(session, group);
401 }
402
403 for (ArtifactResolverPostProcessor artifactResolverPostProcessor :
404 artifactResolverPostProcessors.values()) {
405 artifactResolverPostProcessor.postProcess(session, results);
406 }
407
408 for (ArtifactResult result : results) {
409 ArtifactRequest request = result.getRequest();
410
411 Artifact artifact = result.getArtifact();
412 if (artifact == null || artifact.getPath() == null) {
413 failures = true;
414 if (result.getExceptions().isEmpty()) {
415 Exception exception =
416 new ArtifactNotFoundException(request.getArtifact(), (RemoteRepository) null);
417 result.addException(result.getRepository(), exception);
418 }
419 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
420 artifactResolved(session, trace, request.getArtifact(), null, result.getExceptions());
421 }
422 }
423
424 if (failures) {
425 throw new ArtifactResolutionException(results);
426 }
427
428 return results;
429 }
430 } finally {
431 current.close();
432 }
433 }
434
435
436
437
438
439
440
441
442
443
444
445
446
447 private boolean isLocallyInstalled(LocalArtifactResult lar, VersionResult vr) {
448 if (lar.isAvailable()) {
449 return true;
450 }
451 if (lar.getPath() != null) {
452
453 if (vr.getRepository() instanceof LocalRepository) {
454
455 return true;
456 } else {
457 return vr.getRepository() == null
458 && lar.getRequest().getRepositories().isEmpty();
459 }
460 }
461 return false;
462 }
463
464 private Path getPath(RepositorySystemSession session, Artifact artifact, Path path)
465 throws ArtifactTransferException {
466 if (artifact.isSnapshot()
467 && !artifact.getVersion().equals(artifact.getBaseVersion())
468 && ConfigUtils.getBoolean(
469 session, DEFAULT_SNAPSHOT_NORMALIZATION, CONFIG_PROP_SNAPSHOT_NORMALIZATION)) {
470 String name = path.getFileName().toString().replace(artifact.getVersion(), artifact.getBaseVersion());
471 Path dst = path.getParent().resolve(name);
472
473 try {
474 long pathLastModified = pathProcessor.lastModified(path, 0L);
475 boolean copy = pathProcessor.size(dst, 0L) != pathProcessor.size(path, 0L)
476 || pathProcessor.lastModified(dst, 0L) != pathLastModified;
477 if (copy) {
478 pathProcessor.copyWithTimestamp(path, dst);
479 }
480 } catch (IOException e) {
481 throw new ArtifactTransferException(artifact, null, e);
482 }
483
484 path = dst;
485 }
486
487 return path;
488 }
489
490 private void performDownloads(RepositorySystemSession session, ResolutionGroup group) {
491 List<ArtifactDownload> downloads = gatherDownloads(session, group);
492 if (downloads.isEmpty()) {
493 return;
494 }
495
496 for (ArtifactDownload download : downloads) {
497 artifactDownloading(session, download.getTrace(), download.getArtifact(), group.repository);
498 }
499
500 try {
501 try (RepositoryConnector connector =
502 repositoryConnectorProvider.newRepositoryConnector(session, group.repository)) {
503 connector.get(downloads, null);
504 }
505 } catch (NoRepositoryConnectorException e) {
506 for (ArtifactDownload download : downloads) {
507 download.setException(new ArtifactTransferException(download.getArtifact(), group.repository, e));
508 }
509 }
510
511 evaluateDownloads(session, group);
512 }
513
514 private List<ArtifactDownload> gatherDownloads(RepositorySystemSession session, ResolutionGroup group) {
515 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
516 List<ArtifactDownload> downloads = new ArrayList<>();
517
518 for (ResolutionItem item : group.items) {
519 Artifact artifact = item.artifact;
520
521 if (item.resolved.get()) {
522
523 continue;
524 }
525
526 ArtifactDownload download = new ArtifactDownload();
527 download.setArtifact(artifact);
528 download.setRequestContext(item.request.getRequestContext());
529 download.setListener(SafeTransferListener.wrap(session));
530 download.setTrace(item.trace);
531 if (item.local.getPath() != null) {
532 download.setPath(item.local.getPath());
533 download.setExistenceCheck(true);
534 } else {
535 download.setPath(lrm.getAbsolutePathForRemoteArtifact(
536 artifact, group.repository, item.request.getRequestContext()));
537 }
538
539 boolean snapshot = artifact.isSnapshot();
540 RepositoryPolicy policy = remoteRepositoryManager.getPolicy(session, group.repository, !snapshot, snapshot);
541
542 int errorPolicy = Utils.getPolicy(session, artifact, group.repository);
543 if ((errorPolicy & ResolutionErrorPolicy.CACHE_ALL) != 0) {
544 UpdateCheck<Artifact, ArtifactTransferException> check = new UpdateCheck<>();
545 check.setItem(artifact);
546 check.setPath(download.getPath());
547 check.setFileValid(false);
548 check.setRepository(group.repository);
549 check.setArtifactPolicy(policy.getArtifactUpdatePolicy());
550 check.setMetadataPolicy(policy.getMetadataUpdatePolicy());
551 item.updateCheck = check;
552 updateCheckManager.checkArtifact(session, check);
553 if (!check.isRequired()) {
554 item.result.addException(group.repository, check.getException());
555 continue;
556 }
557 }
558
559 download.setChecksumPolicy(policy.getChecksumPolicy());
560 download.setRepositories(item.repository.getMirroredRepositories());
561 downloads.add(download);
562 item.download = download;
563 }
564
565 return downloads;
566 }
567
568 private void evaluateDownloads(RepositorySystemSession session, ResolutionGroup group) {
569 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
570
571 for (ResolutionItem item : group.items) {
572 ArtifactDownload download = item.download;
573 if (download == null) {
574 continue;
575 }
576
577 Artifact artifact = download.getArtifact();
578 if (download.getException() == null) {
579 item.resolved.set(true);
580 item.result.setRepository(group.repository);
581 try {
582 artifact = artifact.setPath(getPath(session, artifact, download.getPath()));
583 item.result.setArtifact(artifact);
584
585 lrm.add(
586 session,
587 new LocalArtifactRegistration(artifact, group.repository, download.getSupportedContexts()));
588 } catch (ArtifactTransferException e) {
589 download.setException(e);
590 item.result.addException(group.repository, e);
591 }
592 } else {
593 item.result.addException(group.repository, download.getException());
594 }
595
596
597
598
599
600 if (item.updateCheck != null) {
601 item.updateCheck.setException(download.getException());
602 updateCheckManager.touchArtifact(session, item.updateCheck);
603 }
604
605 artifactDownloaded(session, download.getTrace(), artifact, group.repository, download.getException());
606 if (download.getException() == null) {
607 artifactResolved(session, download.getTrace(), artifact, group.repository, null);
608 }
609 }
610 }
611
612 private void artifactResolving(RepositorySystemSession session, RequestTrace trace, Artifact artifact) {
613 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVING);
614 event.setTrace(trace);
615 event.setArtifact(artifact);
616
617 repositoryEventDispatcher.dispatch(event.build());
618 }
619
620 private void artifactResolved(
621 RepositorySystemSession session,
622 RequestTrace trace,
623 Artifact artifact,
624 ArtifactRepository repository,
625 Collection<Exception> exceptions) {
626 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVED);
627 event.setTrace(trace);
628 event.setArtifact(artifact);
629 event.setRepository(repository);
630 event.setExceptions(exceptions != null ? new ArrayList<>(exceptions) : null);
631 if (artifact != null) {
632 event.setPath(artifact.getPath());
633 }
634
635 repositoryEventDispatcher.dispatch(event.build());
636 }
637
638 private void artifactDownloading(
639 RepositorySystemSession session, RequestTrace trace, Artifact artifact, RemoteRepository repository) {
640 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADING);
641 event.setTrace(trace);
642 event.setArtifact(artifact);
643 event.setRepository(repository);
644
645 repositoryEventDispatcher.dispatch(event.build());
646 }
647
648 private void artifactDownloaded(
649 RepositorySystemSession session,
650 RequestTrace trace,
651 Artifact artifact,
652 RemoteRepository repository,
653 Exception exception) {
654 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADED);
655 event.setTrace(trace);
656 event.setArtifact(artifact);
657 event.setRepository(repository);
658 event.setException(exception);
659 if (artifact != null) {
660 event.setPath(artifact.getPath());
661 }
662
663 repositoryEventDispatcher.dispatch(event.build());
664 }
665
666 static class ResolutionGroup {
667
668 final RemoteRepository repository;
669
670 final List<ResolutionItem> items = new ArrayList<>();
671
672 ResolutionGroup(RemoteRepository repository) {
673 this.repository = repository;
674 }
675
676 boolean matches(RemoteRepository repo) {
677 return repository.getUrl().equals(repo.getUrl())
678 && repository.getContentType().equals(repo.getContentType())
679 && repository.isRepositoryManager() == repo.isRepositoryManager();
680 }
681 }
682
683 static class ResolutionItem {
684
685 final RequestTrace trace;
686
687 final ArtifactRequest request;
688
689 final ArtifactResult result;
690
691 final LocalArtifactResult local;
692
693 final RemoteRepository repository;
694
695 final Artifact artifact;
696
697 final AtomicBoolean resolved;
698
699 ArtifactDownload download;
700
701 UpdateCheck<Artifact, ArtifactTransferException> updateCheck;
702
703 ResolutionItem(
704 RequestTrace trace,
705 Artifact artifact,
706 AtomicBoolean resolved,
707 ArtifactResult result,
708 LocalArtifactResult local,
709 RemoteRepository repository) {
710 this.trace = trace;
711 this.artifact = artifact;
712 this.resolved = resolved;
713 this.result = result;
714 this.request = result.getRequest();
715 this.local = local;
716 this.repository = repository;
717 }
718 }
719 }