in maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultMetadataResolver.java [153:375]
private List<MetadataResult> resolve(
SyncContext shared,
SyncContext exclusive,
Collection<Metadata> subjects,
RepositorySystemSession session,
Collection<? extends MetadataRequest> requests) {
SyncContext current = shared;
try {
while (true) {
current.acquire(null, subjects);
final List<MetadataResult> results = new ArrayList<>(requests.size());
final List<ResolveTask> tasks = new ArrayList<>(requests.size());
final Map<Path, Long> localLastUpdates = new HashMap<>();
final RemoteRepositoryFilter remoteRepositoryFilter =
remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
for (MetadataRequest request : requests) {
RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
MetadataResult result = new MetadataResult(request);
results.add(result);
Metadata metadata = request.getMetadata();
RemoteRepository repository = request.getRepository();
if (repository == null) {
LocalRepository localRepo =
session.getLocalRepositoryManager().getRepository();
metadataResolving(session, trace, metadata, localRepo);
Path localFile = getLocalFile(session, metadata);
if (localFile != null) {
metadata = metadata.setPath(localFile);
result.setMetadata(metadata);
} else {
result.setException(new MetadataNotFoundException(metadata, localRepo));
}
metadataResolved(session, trace, metadata, localRepo, result.getException());
continue;
}
if (remoteRepositoryFilter != null) {
RemoteRepositoryFilter.Result filterResult =
remoteRepositoryFilter.acceptMetadata(repository, metadata);
if (!filterResult.isAccepted()) {
result.setException(
new MetadataNotFoundException(metadata, repository, filterResult.reasoning()));
continue;
}
}
List<RemoteRepository> repositories =
getEnabledSourceRepositories(repository, metadata.getNature());
if (repositories.isEmpty()) {
continue;
}
metadataResolving(session, trace, metadata, repository);
LocalRepositoryManager lrm = session.getLocalRepositoryManager();
LocalMetadataRequest localRequest =
new LocalMetadataRequest(metadata, repository, request.getRequestContext());
LocalMetadataResult lrmResult = lrm.find(session, localRequest);
Path metadataPath = lrmResult.getPath();
try {
Utils.checkOffline(session, offlineController, repository);
} catch (RepositoryOfflineException e) {
if (metadataPath != null) {
metadata = metadata.setPath(metadataPath);
result.setMetadata(metadata);
} else {
String msg = "Cannot access " + repository.getId() + " (" + repository.getUrl()
+ ") in offline mode and the metadata " + metadata
+ " has not been downloaded from it before";
result.setException(new MetadataNotFoundException(metadata, repository, msg, e));
}
metadataResolved(session, trace, metadata, repository, result.getException());
continue;
}
Long localLastUpdate = null;
if (request.isFavorLocalRepository()) {
Path localPath = getLocalFile(session, metadata);
localLastUpdate = localLastUpdates.get(localPath);
if (localLastUpdate == null) {
localLastUpdate = localPath != null ? pathProcessor.lastModified(localPath, 0L) : 0L;
localLastUpdates.put(localPath, localLastUpdate);
}
}
List<UpdateCheck<Metadata, MetadataTransferException>> checks = new ArrayList<>();
Exception exception = null;
for (RemoteRepository repo : repositories) {
RepositoryPolicy policy = getPolicy(session, repo, metadata.getNature());
UpdateCheck<Metadata, MetadataTransferException> check = new UpdateCheck<>();
check.setLocalLastUpdated((localLastUpdate != null) ? localLastUpdate : 0);
check.setItem(metadata);
// use 'main' installation file for the check (-> use requested repository)
Path checkPath = session.getLocalRepositoryManager()
.getAbsolutePathForRemoteMetadata(metadata, repository, request.getRequestContext());
check.setPath(checkPath);
check.setRepository(repository);
check.setAuthoritativeRepository(repo);
check.setArtifactPolicy(policy.getArtifactUpdatePolicy());
check.setMetadataPolicy(policy.getMetadataUpdatePolicy());
if (lrmResult.isStale()) {
checks.add(check);
} else {
updateCheckManager.checkMetadata(session, check);
if (check.isRequired()) {
checks.add(check);
} else if (exception == null) {
exception = check.getException();
}
}
}
if (!checks.isEmpty()) {
RepositoryPolicy policy = getPolicy(session, repository, metadata.getNature());
// install path may be different from lookup path
Path installPath = session.getLocalRepositoryManager()
.getAbsolutePathForRemoteMetadata(
metadata, request.getRepository(), request.getRequestContext());
ResolveTask task = new ResolveTask(
session, trace, result, installPath, checks, policy.getChecksumPolicy());
tasks.add(task);
} else {
result.setException(exception);
if (metadataPath != null) {
metadata = metadata.setPath(metadataPath);
result.setMetadata(metadata);
}
metadataResolved(session, trace, metadata, repository, result.getException());
}
}
if (!tasks.isEmpty() && current == shared) {
current.close();
current = exclusive;
continue;
}
if (!tasks.isEmpty()) {
int threads = ExecutorUtils.threadCount(session, DEFAULT_THREADS, CONFIG_PROP_THREADS);
Executor executor = ExecutorUtils.executor(
Math.min(tasks.size(), threads), getClass().getSimpleName() + '-');
try {
RunnableErrorForwarder errorForwarder = new RunnableErrorForwarder();
for (ResolveTask task : tasks) {
metadataDownloading(
task.session, task.trace, task.request.getMetadata(), task.request.getRepository());
executor.execute(errorForwarder.wrap(task));
}
errorForwarder.await();
for (ResolveTask task : tasks) {
/*
* NOTE: Touch after registration with local repo to ensure concurrent resolution is not
* rejected with "already updated" via session data when actual update to local repo is
* still pending.
*/
for (UpdateCheck<Metadata, MetadataTransferException> check : task.checks) {
updateCheckManager.touchMetadata(task.session, check.setException(task.exception));
}
metadataDownloaded(
session,
task.trace,
task.request.getMetadata(),
task.request.getRepository(),
task.metadataPath,
task.exception);
task.result.setException(task.exception);
}
} finally {
ExecutorUtils.shutdown(executor);
}
for (ResolveTask task : tasks) {
Metadata metadata = task.request.getMetadata();
// re-lookup metadata for resolve
LocalMetadataRequest localRequest = new LocalMetadataRequest(
metadata, task.request.getRepository(), task.request.getRequestContext());
Path metadataPath = session.getLocalRepositoryManager()
.find(session, localRequest)
.getPath();
if (metadataPath != null) {
metadata = metadata.setPath(metadataPath);
task.result.setMetadata(metadata);
}
if (task.result.getException() == null) {
task.result.setUpdated(true);
}
metadataResolved(
session,
task.trace,
metadata,
task.request.getRepository(),
task.result.getException());
}
}
return results;
}
} finally {
current.close();
}
}