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
123
124
125
126
127
128
129
130
131
132
133
134
135 public static final String CONFIG_PROP_EXISTENCE_CHECK_RELABEL = CONFIG_PROPS_PREFIX + "existenceCheckRelabel";
136
137 public static final boolean DEFAULT_EXISTENCE_CHECK_RELABEL = false;
138
139 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultArtifactResolver.class);
140
141 private final PathProcessor pathProcessor;
142
143 private final RepositoryEventDispatcher repositoryEventDispatcher;
144
145 private final VersionResolver versionResolver;
146
147 private final UpdateCheckManager updateCheckManager;
148
149 private final RepositoryConnectorProvider repositoryConnectorProvider;
150
151 private final RemoteRepositoryManager remoteRepositoryManager;
152
153 private final SyncContextFactory syncContextFactory;
154
155 private final OfflineController offlineController;
156
157 private final Map<String, ArtifactResolverPostProcessor> artifactResolverPostProcessors;
158
159 private final RemoteRepositoryFilterManager remoteRepositoryFilterManager;
160
161 @SuppressWarnings("checkstyle:parameternumber")
162 @Inject
163 public DefaultArtifactResolver(
164 PathProcessor pathProcessor,
165 RepositoryEventDispatcher repositoryEventDispatcher,
166 VersionResolver versionResolver,
167 UpdateCheckManager updateCheckManager,
168 RepositoryConnectorProvider repositoryConnectorProvider,
169 RemoteRepositoryManager remoteRepositoryManager,
170 SyncContextFactory syncContextFactory,
171 OfflineController offlineController,
172 Map<String, ArtifactResolverPostProcessor> artifactResolverPostProcessors,
173 RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
174 this.pathProcessor = requireNonNull(pathProcessor, "path processor cannot be null");
175 this.repositoryEventDispatcher =
176 requireNonNull(repositoryEventDispatcher, "repository event dispatcher cannot be null");
177 this.versionResolver = requireNonNull(versionResolver, "version resolver cannot be null");
178 this.updateCheckManager = requireNonNull(updateCheckManager, "update check manager cannot be null");
179 this.repositoryConnectorProvider =
180 requireNonNull(repositoryConnectorProvider, "repository connector provider cannot be null");
181 this.remoteRepositoryManager =
182 requireNonNull(remoteRepositoryManager, "remote repository provider cannot be null");
183 this.syncContextFactory = requireNonNull(syncContextFactory, "sync context factory cannot be null");
184 this.offlineController = requireNonNull(offlineController, "offline controller cannot be null");
185 this.artifactResolverPostProcessors =
186 requireNonNull(artifactResolverPostProcessors, "artifact resolver post-processors cannot be null");
187 this.remoteRepositoryFilterManager =
188 requireNonNull(remoteRepositoryFilterManager, "remote repository filter manager cannot be null");
189 }
190
191 @Override
192 public ArtifactResult resolveArtifact(RepositorySystemSession session, ArtifactRequest request)
193 throws ArtifactResolutionException {
194 requireNonNull(session, "session cannot be null");
195 requireNonNull(request, "request cannot be null");
196
197 return resolveArtifacts(session, Collections.singleton(request)).get(0);
198 }
199
200 @Override
201 public List<ArtifactResult> resolveArtifacts(
202 RepositorySystemSession session, Collection<? extends ArtifactRequest> requests)
203 throws ArtifactResolutionException {
204 requireNonNull(session, "session cannot be null");
205 requireNonNull(requests, "requests cannot be null");
206 Collection<Artifact> artifacts = new ArrayList<>(requests.size());
207 SystemDependencyScope systemDependencyScope = session.getSystemDependencyScope();
208 for (ArtifactRequest request : requests) {
209 if (systemDependencyScope != null && systemDependencyScope.getSystemPath(request.getArtifact()) != null) {
210 continue;
211 }
212 artifacts.add(request.getArtifact());
213 }
214
215 try (SyncContext shared = new CloseOnceSyncContext(syncContextFactory.newInstance(session, true));
216 SyncContext exclusive = new CloseOnceSyncContext(syncContextFactory.newInstance(session, false))) {
217 return resolve(shared, exclusive, artifacts, session, requests);
218 }
219 }
220
221 @SuppressWarnings("checkstyle:methodlength")
222 private List<ArtifactResult> resolve(
223 SyncContext shared,
224 SyncContext exclusive,
225 Collection<Artifact> subjects,
226 RepositorySystemSession session,
227 Collection<? extends ArtifactRequest> requests)
228 throws ArtifactResolutionException {
229 SystemDependencyScope systemDependencyScope = session.getSystemDependencyScope();
230 SyncContext current = shared;
231 try {
232 while (true) {
233 current.acquire(subjects, null);
234
235 boolean failures = false;
236 final List<ArtifactResult> results = new ArrayList<>(requests.size());
237 final boolean simpleLrmInterop =
238 ConfigUtils.getBoolean(session, DEFAULT_SIMPLE_LRM_INTEROP, CONFIG_PROP_SIMPLE_LRM_INTEROP);
239 final LocalRepositoryManager lrm = session.getLocalRepositoryManager();
240 final WorkspaceReader workspace = session.getWorkspaceReader();
241 final List<ResolutionGroup> groups = new ArrayList<>();
242
243 final RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
244
245 for (ArtifactRequest request : requests) {
246 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
247
248 ArtifactResult result = new ArtifactResult(request);
249 results.add(result);
250
251 Artifact artifact = request.getArtifact();
252
253 if (current == shared) {
254 artifactResolving(session, trace, artifact);
255 }
256
257 String localPath =
258 systemDependencyScope != null ? systemDependencyScope.getSystemPath(artifact) : null;
259 if (localPath != null) {
260
261 Path path = Paths.get(localPath);
262 if (!Files.isRegularFile(path)) {
263 failures = true;
264 result.addException(
265 ArtifactResult.NO_REPOSITORY, new ArtifactNotFoundException(artifact, localPath));
266 } else {
267 artifact = artifact.setPath(path);
268 result.setArtifact(artifact);
269 artifactResolved(session, trace, artifact, null, result.getExceptions());
270 }
271 continue;
272 }
273
274 List<RemoteRepository> remoteRepositories = request.getRepositories();
275 List<RemoteRepository> filteredRemoteRepositories = new ArrayList<>(remoteRepositories);
276 if (filter != null) {
277 for (RemoteRepository repository : remoteRepositories) {
278 if (!repository.getPolicy(artifact.isSnapshot()).isEnabled()) {
279 filteredRemoteRepositories.remove(repository);
280 continue;
281 }
282 RemoteRepositoryFilter.Result filterResult = filter.acceptArtifact(repository, artifact);
283 if (!filterResult.isAccepted()) {
284 result.addException(
285 repository,
286 new ArtifactFilteredOutException(
287 artifact, repository, filterResult.reasoning()));
288 filteredRemoteRepositories.remove(repository);
289 }
290 }
291 }
292
293 VersionResult versionResult;
294 try {
295 VersionRequest versionRequest =
296 new VersionRequest(artifact, filteredRemoteRepositories, request.getRequestContext());
297 versionRequest.setTrace(trace);
298 versionResult = versionResolver.resolveVersion(session, versionRequest);
299 } catch (VersionResolutionException e) {
300 if (filteredRemoteRepositories.isEmpty()) {
301 result.addException(lrm.getRepository(), e);
302 } else {
303 filteredRemoteRepositories.forEach(r -> result.addException(r, e));
304 }
305 continue;
306 }
307
308 artifact = artifact.setVersion(versionResult.getVersion());
309
310 if (artifact.getVersion().trim().isEmpty()) {
311
312
313
314 result.addException(
315 ArtifactResult.NO_REPOSITORY,
316 new ArtifactNotFoundException(
317 artifact,
318 (RemoteRepository) null,
319 "The version of " + artifact + " is missing or blank"));
320 continue;
321 }
322
323 if (versionResult.getRepository() != null) {
324 if (versionResult.getRepository() instanceof RemoteRepository) {
325 filteredRemoteRepositories =
326 Collections.singletonList((RemoteRepository) versionResult.getRepository());
327 } else {
328 filteredRemoteRepositories = Collections.emptyList();
329 }
330 }
331
332 if (workspace != null) {
333 Path path = workspace.findArtifactPath(artifact);
334 if (path != null) {
335 artifact = artifact.setPath(path);
336 result.setArtifact(artifact);
337 result.setRepository(workspace.getRepository());
338 artifactResolved(session, trace, artifact, result.getRepository(), null);
339 continue;
340 }
341 }
342
343 LocalArtifactResult local = lrm.find(
344 session,
345 new LocalArtifactRequest(
346 artifact, filteredRemoteRepositories, request.getRequestContext()));
347 result.setLocalArtifactResult(local);
348 boolean found = (filter != null && local.isAvailable())
349 || (filter == null && isLocallyInstalled(local, versionResult));
350
351
352
353 if (found) {
354 if (local.getRepository() != null) {
355 result.setRepository(local.getRepository());
356 } else {
357 result.setRepository(lrm.getRepository());
358 }
359
360 try {
361 Path localArtifactPath = local.getPath();
362 artifact = artifact.setPath(getPath(session, artifact, localArtifactPath));
363 result.setArtifact(artifact);
364 if (local.getRepository() != null && !localArtifactPath.equals(artifact.getPath())) {
365
366
367
368
369
370
371 lrm.add(
372 session,
373 new LocalArtifactRegistration(
374 artifact.setVersion(artifact.getBaseVersion()),
375 local.getRepository(),
376 Collections.singleton(request.getRequestContext())));
377 }
378 artifactResolved(session, trace, artifact, result.getRepository(), null);
379 } catch (ArtifactTransferException e) {
380 result.addException(lrm.getRepository(), e);
381 }
382 if (filter == null && simpleLrmInterop && !local.isAvailable()) {
383
384
385
386
387
388
389 lrm.add(session, new LocalArtifactRegistration(artifact));
390 }
391
392 continue;
393 }
394
395 if (local.getPath() != null) {
396 LOGGER.info(
397 "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 {}",
398 LogSanitizer.sanitize(String.valueOf(artifact)),
399 LogSanitizer.sanitize(String.valueOf(remoteRepositories)));
400 }
401
402 LOGGER.debug(
403 "Resolving artifact {} from {}",
404 LogSanitizer.sanitize(String.valueOf(artifact)),
405 LogSanitizer.sanitize(String.valueOf(remoteRepositories)));
406 AtomicBoolean resolved = new AtomicBoolean(false);
407 Iterator<ResolutionGroup> groupIt = groups.iterator();
408 for (RemoteRepository repo : filteredRemoteRepositories) {
409 if (!repo.getPolicy(artifact.isSnapshot()).isEnabled()) {
410 continue;
411 }
412
413 try {
414 Utils.checkOffline(session, offlineController, repo);
415 } catch (RepositoryOfflineException e) {
416 Exception exception = new ArtifactNotFoundException(
417 artifact,
418 repo,
419 "Cannot access " + repo.getId() + " ("
420 + repo.getUrl() + ") in offline mode and the artifact " + artifact
421 + " has not been downloaded from it before.",
422 e);
423 result.addException(repo, exception);
424 continue;
425 }
426
427 ResolutionGroup group = null;
428 while (groupIt.hasNext()) {
429 ResolutionGroup t = groupIt.next();
430 if (t.matches(repo)) {
431 group = t;
432 break;
433 }
434 }
435 if (group == null) {
436 group = new ResolutionGroup(repo);
437 groups.add(group);
438 groupIt = Collections.emptyIterator();
439 }
440 group.items.add(new ResolutionItem(trace, artifact, resolved, result, local, repo));
441 }
442 }
443
444 if (!groups.isEmpty() && current == shared) {
445 SyncContext sharedContext = current;
446 current = exclusive;
447 sharedContext.close();
448 continue;
449 }
450
451 for (ResolutionGroup group : groups) {
452 performDownloads(session, group);
453 }
454
455 for (ArtifactResolverPostProcessor artifactResolverPostProcessor :
456 artifactResolverPostProcessors.values()) {
457 artifactResolverPostProcessor.postProcess(session, results);
458 }
459
460 for (ArtifactResult result : results) {
461 ArtifactRequest request = result.getRequest();
462
463 Artifact artifact = result.getArtifact();
464 if (artifact == null || artifact.getPath() == null) {
465 failures = true;
466 if (result.getExceptions().isEmpty()) {
467 Exception exception =
468 new ArtifactNotFoundException(request.getArtifact(), (RemoteRepository) null);
469
470
471
472 result.addException(
473 result.getRepository() != null
474 ? result.getRepository()
475 : ArtifactResult.NO_REPOSITORY,
476 exception);
477 }
478 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
479 artifactResolved(session, trace, request.getArtifact(), null, result.getExceptions());
480 }
481 }
482
483 if (failures) {
484 throw new ArtifactResolutionException(results);
485 }
486
487 return results;
488 }
489 } finally {
490 try {
491 current.close();
492 } finally {
493 if (current == shared) {
494 exclusive.close();
495 }
496 }
497 }
498 }
499
500
501
502
503
504
505
506
507
508
509
510
511
512 private boolean isLocallyInstalled(LocalArtifactResult lar, VersionResult vr) {
513 if (lar.isAvailable()) {
514 return true;
515 }
516 if (lar.getPath() != null) {
517
518 if (vr.getRepository() instanceof LocalRepository) {
519
520 return true;
521 } else {
522 return vr.getRepository() == null
523 && lar.getRequest().getRepositories().isEmpty();
524 }
525 }
526 return false;
527 }
528
529 private Path getPath(RepositorySystemSession session, Artifact artifact, Path path)
530 throws ArtifactTransferException {
531 if (artifact.isSnapshot()
532 && !artifact.getVersion().equals(artifact.getBaseVersion())
533 && ConfigUtils.getBoolean(
534 session, DEFAULT_SNAPSHOT_NORMALIZATION, CONFIG_PROP_SNAPSHOT_NORMALIZATION)) {
535 String name = path.getFileName().toString().replace(artifact.getVersion(), artifact.getBaseVersion());
536 Path dst = path.getParent().resolve(name);
537
538 try {
539 long pathLastModified = pathProcessor.lastModified(path, 0L);
540 boolean copy = pathProcessor.size(dst, 0L) != pathProcessor.size(path, 0L)
541 || pathProcessor.lastModified(dst, 0L) != pathLastModified;
542 if (copy) {
543 pathProcessor.copyWithTimestamp(path, dst);
544 }
545 } catch (IOException e) {
546 throw new ArtifactTransferException(artifact, null, e);
547 }
548
549 path = dst;
550 }
551
552 return path;
553 }
554
555 private void performDownloads(RepositorySystemSession session, ResolutionGroup group) {
556 List<ArtifactDownload> downloads = gatherDownloads(session, group);
557 if (downloads.isEmpty()) {
558 return;
559 }
560
561 for (ArtifactDownload download : downloads) {
562 artifactDownloading(session, download.getTrace(), download.getArtifact(), group.repository);
563 }
564
565 try {
566 try (RepositoryConnector connector =
567 repositoryConnectorProvider.newRepositoryConnector(session, group.repository)) {
568 connector.get(downloads, null);
569 }
570 } catch (NoRepositoryConnectorException e) {
571 for (ArtifactDownload download : downloads) {
572 download.setException(new ArtifactTransferException(download.getArtifact(), group.repository, e));
573 }
574 }
575
576 evaluateDownloads(session, group);
577 }
578
579 private List<ArtifactDownload> gatherDownloads(RepositorySystemSession session, ResolutionGroup group) {
580 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
581 final boolean existenceCheckRelabel =
582 ConfigUtils.getBoolean(session, DEFAULT_EXISTENCE_CHECK_RELABEL, CONFIG_PROP_EXISTENCE_CHECK_RELABEL);
583 List<ArtifactDownload> downloads = new ArrayList<>();
584
585 for (ResolutionItem item : group.items) {
586 Artifact artifact = item.artifact;
587
588 if (item.resolved.get()) {
589
590 continue;
591 }
592
593 ArtifactDownload download = new ArtifactDownload();
594 download.setArtifact(artifact);
595 download.setRequestContext(item.request.getRequestContext());
596 download.setListener(SafeTransferListener.wrap(session));
597 download.setTrace(item.trace);
598 if (item.local.getPath() != null && existenceCheckRelabel) {
599
600
601
602
603 download.setPath(item.local.getPath());
604 download.setExistenceCheck(true);
605 } else {
606
607
608
609
610
611 download.setPath(lrm.getAbsolutePathForRemoteArtifact(
612 artifact, group.repository, item.request.getRequestContext()));
613 }
614
615 boolean snapshot = artifact.isSnapshot();
616 RepositoryPolicy policy = remoteRepositoryManager.getPolicy(session, group.repository, !snapshot, snapshot);
617
618 int errorPolicy = Utils.getPolicy(session, artifact, group.repository);
619 if ((errorPolicy & ResolutionErrorPolicy.CACHE_ALL) != 0) {
620 UpdateCheck<Artifact, ArtifactTransferException> check = new UpdateCheck<>();
621 check.setItem(artifact);
622 check.setPath(download.getPath());
623 check.setFileValid(false);
624 check.setRepository(group.repository);
625 check.setArtifactPolicy(policy.getArtifactUpdatePolicy());
626 check.setMetadataPolicy(policy.getMetadataUpdatePolicy());
627 item.updateCheck = check;
628 updateCheckManager.checkArtifact(session, check);
629 if (!check.isRequired()) {
630 item.result.addException(group.repository, check.getException());
631 continue;
632 }
633 }
634
635 download.setChecksumPolicy(policy.getChecksumPolicy());
636 download.setRepositories(item.repository.getMirroredRepositories());
637 downloads.add(download);
638 item.download = download;
639 }
640
641 return downloads;
642 }
643
644 private void evaluateDownloads(RepositorySystemSession session, ResolutionGroup group) {
645 LocalRepositoryManager lrm = session.getLocalRepositoryManager();
646
647 for (ResolutionItem item : group.items) {
648 ArtifactDownload download = item.download;
649 if (download == null) {
650 continue;
651 }
652
653 Artifact artifact = download.getArtifact();
654 if (download.getException() == null) {
655 item.resolved.set(true);
656 item.result.setRepository(group.repository);
657 try {
658 artifact = artifact.setPath(getPath(session, artifact, download.getPath()));
659 item.result.setArtifact(artifact);
660
661 lrm.add(
662 session,
663 new LocalArtifactRegistration(artifact, group.repository, download.getSupportedContexts()));
664 if (!download.getPath().equals(artifact.getPath())) {
665
666
667
668
669
670
671
672 lrm.add(
673 session,
674 new LocalArtifactRegistration(
675 artifact.setVersion(artifact.getBaseVersion()),
676 group.repository,
677 download.getSupportedContexts()));
678 }
679 } catch (ArtifactTransferException e) {
680 download.setException(e);
681 item.result.addException(group.repository, e);
682 }
683 } else {
684 item.result.addException(group.repository, download.getException());
685 }
686
687
688
689
690
691 if (item.updateCheck != null) {
692 item.updateCheck.setException(download.getException());
693 updateCheckManager.touchArtifact(session, item.updateCheck);
694 }
695
696 artifactDownloaded(session, download.getTrace(), artifact, group.repository, download.getException());
697 if (download.getException() == null) {
698 artifactResolved(session, download.getTrace(), artifact, group.repository, null);
699 }
700 }
701 }
702
703 private void artifactResolving(RepositorySystemSession session, RequestTrace trace, Artifact artifact) {
704 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVING);
705 event.setTrace(trace);
706 event.setArtifact(artifact);
707
708 repositoryEventDispatcher.dispatch(event.build());
709 }
710
711 private void artifactResolved(
712 RepositorySystemSession session,
713 RequestTrace trace,
714 Artifact artifact,
715 ArtifactRepository repository,
716 Collection<Exception> exceptions) {
717 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_RESOLVED);
718 event.setTrace(trace);
719 event.setArtifact(artifact);
720 event.setRepository(repository);
721 event.setExceptions(exceptions != null ? new ArrayList<>(exceptions) : null);
722 if (artifact != null) {
723 event.setPath(artifact.getPath());
724 }
725
726 repositoryEventDispatcher.dispatch(event.build());
727 }
728
729 private void artifactDownloading(
730 RepositorySystemSession session, RequestTrace trace, Artifact artifact, RemoteRepository repository) {
731 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADING);
732 event.setTrace(trace);
733 event.setArtifact(artifact);
734 event.setRepository(repository);
735
736 repositoryEventDispatcher.dispatch(event.build());
737 }
738
739 private void artifactDownloaded(
740 RepositorySystemSession session,
741 RequestTrace trace,
742 Artifact artifact,
743 RemoteRepository repository,
744 Exception exception) {
745 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DOWNLOADED);
746 event.setTrace(trace);
747 event.setArtifact(artifact);
748 event.setRepository(repository);
749 event.setException(exception);
750 if (artifact != null) {
751 event.setPath(artifact.getPath());
752 }
753
754 repositoryEventDispatcher.dispatch(event.build());
755 }
756
757 static class ResolutionGroup {
758
759 final RemoteRepository repository;
760
761 final List<ResolutionItem> items = new ArrayList<>();
762
763 ResolutionGroup(RemoteRepository repository) {
764 this.repository = repository;
765 }
766
767 boolean matches(RemoteRepository repo) {
768 return repository.getUrl().equals(repo.getUrl())
769 && repository.getContentType().equals(repo.getContentType())
770 && repository.isRepositoryManager() == repo.isRepositoryManager();
771 }
772 }
773
774 static class ResolutionItem {
775
776 final RequestTrace trace;
777
778 final ArtifactRequest request;
779
780 final ArtifactResult result;
781
782 final LocalArtifactResult local;
783
784 final RemoteRepository repository;
785
786 final Artifact artifact;
787
788 final AtomicBoolean resolved;
789
790 ArtifactDownload download;
791
792 UpdateCheck<Artifact, ArtifactTransferException> updateCheck;
793
794 ResolutionItem(
795 RequestTrace trace,
796 Artifact artifact,
797 AtomicBoolean resolved,
798 ArtifactResult result,
799 LocalArtifactResult local,
800 RemoteRepository repository) {
801 this.trace = trace;
802 this.artifact = artifact;
803 this.resolved = resolved;
804 this.result = result;
805 this.request = result.getRequest();
806 this.local = local;
807 this.repository = repository;
808 }
809 }
810 }