private List resolve()

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();
        }
    }