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